线程的两种实现方式,以及区别

-  让类成为线程类有两种方式,实现Runnable接口,以及继承Thread类(类中实现了Runnable接口,还提供了一些额外的方法)。 java

1、Runnable相对优点:

  • java的单继承,当继承了Thread类,则不能继承其余类,而实现Runnable接口能够

  • 实现Runnable接口的线程类的多个线程,能够访问同一变量,而Thread则不能(多窗口买票问题)

缘由:两种方式启动方式不一样:多线程

 

  • Runnable线程类是实例化一个对象o以后,经过屡次new Thread(o).start();启动多个线程,而这几个线程属于一个对象,对象的成员变量是同一个。
  • Thread线程类启动多个线程须要 new MyThread().start();每一个线程启动都对应多个对象,他们的成员变量是独立的。

 测试代码以下:ide

(1)实现Runnable:测试

 1 package com.loan.entity;  2  
 3 import lombok.Data;  4  
 5 @Data  6 public class Test2 implements Runnable{  7 private int ticket=100;  8 @Override  9 public void run() { 10     // TODO Auto-generated method stub
11     while(true){ 12         if(ticket>0){ 13             System.out.println(Thread.currentThread().getName()+"...is saling,余票:"+ticket--); 14  } 15  } 16 } 17 public static void main(String[] args) { 18     Test2 t=new Test2();//只能使用同一个t
19     new Thread(t).start(); 20     new Thread(t).start(); 21     new Thread(t).start(); 22     new Thread(t).start(); 23 } 24 }

 

运行结果:

(2)继承Thread

 1 package com.loan.entity;  2  
 3 public class Test3 extends Thread{  4     int ticket=100;  5     public void run(){  6         while(true){  7             if(ticket>0){  8                 System.out.println(Thread.currentThread().getName()+"...is saling,余票:"+ticket--);  9  } 10  } 11  } 12     public static void main(String[] args) { 13         new Test3().start(); 14         new Test3().start(); 15         new Test3().start(); 16         new Test3().start(); 17  } 18 }

很明显,上面这种方式是错误的!

继承Thread类也能够经过内部类发方式实现。代码以下:

 1 package com.loan.entity;  2  
 3 public class Test3{  4     private  int ticket=100;  5     class InnerClass extends Thread{  6         private Test3 t3;  7  InnerClass(Test3 t){  8             t3=t;  9  } 10         public void run(){ 11             while(true){ 12                 if(ticket>0){ 13                     ticket--; 14                     System.out.println(Thread.currentThread().getName()+"...is saling,余票:"+ticket); 15  } 16  } 17  } 18  } 19     public static void main(String[] args) { 20         Test3 test3=new Test3(); 21         Thread t1=test3.new InnerClass(test3); 22         Thread t2=test3.new InnerClass(test3); 23         Thread t3=test3.new InnerClass(test3); 24         Thread t4=test3.new InnerClass(test3); 25         t1.setName("t1"); 26         t2.setName("t2"); 27         t3.setName("t3"); 28         t4.setName("t4"); 29  t1.start(); 30  t2.start(); 31  t3.start(); 32  t4.start(); 33  } 34 }

 

运行结果:

2、Thread优点

一、使用线程的方法方便一些,例如:获取线程的Id(Thread.currentThread().getId())、线程名(Thread.currentThread().getName())、线程状态(Thread.currentThread().getState())等

二、操做同一变量,可是线程调用run方法内容不一样时,使用Thread内部类的方式进行,例如生产者、消费者模式

生产者消费者多线程例子:

 1 package com.loan.entity;  2  
 3 public class Store {  4     private final int MAX_SIZE=2;//仓库总共可存放货物
 5     private int count=0;//当前仓库货物
 6     public synchronized void add() throws InterruptedException{  7         while(count>=MAX_SIZE){  8             System.out.println("仓库已满");  9             System.out.println(Thread.currentThread().getName()+"等待中。。。。"); 10             this.wait(); 11  } 12             count++; 13             System.out.println(Thread.currentThread().getName()+"存入仓库,当前货物数:"+count); 14             this.notify(); 15  } 16     public synchronized void remove() throws InterruptedException{ 17         while(count<=0){ 18             System.out.println("仓库空了"); 19             System.out.println(Thread.currentThread().getName()+"等待中。。。。"); 20             this.wait(); 21  } 22             count--; 23             System.out.println(Thread.currentThread().getName()+"取出货物,当前货物数:"+count); 24             this.notify(); 25  } 26     public static void main(String[] args) { 27         Store s=new Store(); 28         Thread producer1=s.new Producer(s);//成员内部类需经过对象访问
29         Thread producer2=s.new Producer(s); 30         Thread consumer1=s.new Consumer(s); 31         Thread consumer2=s.new Consumer(s); 32         producer1.setName("producer1");//利用Thread中的方法
33         producer2.setName("producer2"); 34         consumer1.setName("consumer1"); 35         consumer2.setName("consumer2"); 36  producer1.start(); 37  producer2.start(); 38  consumer1.start(); 39  consumer2.start(); 40  } 41     class Producer extends Thread{ 42         private Store store; 43  Producer(Store s){ 44             store=s; 45  } 46         public void run(){ 47             while(true){ 48                 try { 49  store.add(); 50                     Thread.sleep(10000); 51                 } catch (InterruptedException e) { 52                     // TODO Auto-generated catch block
53  e.printStackTrace(); 54  } 55  } 56  } 57  } 58     class Consumer extends Thread{ 59         private Store store; 60  Consumer(Store s){ 61             store=s; 62  } 63         public void run(){ 64             while(true){ 65                 try { 66  store.remove(); 67                     Thread.sleep(15000); 68                 } catch (InterruptedException e) { 69                     // TODO Auto-generated catch block
70  e.printStackTrace(); 71  } 72  } 73  } 74  } 75 }

 

运行结果:

相关文章
相关标签/搜索