你的位置:首页 > Java教程

[Java教程]黑马程序员系列第二篇 多线程(2)


 ASP.Net+Android+IOS开发  、Net培训、期待与您交流!

 

(前言:本篇文章主要依据毕向东老师的课程视频整理而成,如要详细学习,请观看毕老师视频  百度网盘链接地址:http://pan.baidu.com/s/1sjQRHDz)

 

目录:1、线程通信--生产消费者示例(线程通信安全、等待唤醒机制)    2、停止线程、及其会出现的问题、及解决的办法    3、守护线程及几个Thread的方法                   4、工作中线程的常见写法

        1、线程通信--生产消费者示例

代码示例:

 1 public class ProducerConsumer { 2 //需求:生产和消费行为依次进行。   设置产品为BMW  设置生产者和消费者线程各两个 3   public static void main(String[] args) { 4      5     Product pro=new Product(); 6      7     new Thread(new Producter(pro)).start();     8     new Thread(new Consumer(pro)).start(); 9     new Thread(new Producter(pro)).start();10     new Thread(new Consumer(pro)).start();11 12   }13 }14 class Product{15   16   private String name;17   private int No=1;18   boolean flag=false;19   20   public synchronized void set(String names){21     while(flag)22       try {23         this.wait();//等待状态        24       } catch (InterruptedException e) {25         e.printStackTrace();26       }  27        this.name=names+"---"+this.No++;28        System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");      29         flag=true;30         this.notifyAll();//唤醒所有线程31   }  32   public synchronized void out(){33     while(!flag)34       try {35         this.wait();//等待状态36       } catch (InterruptedException e) {37         e.printStackTrace();38       }    39     System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");    40        flag=false;41        this.notifyAll();//唤醒所有线程42   }43 }44 //生产者45 class Producter implements Runnable{46   private Product p;47   public Producter(Product pr){48     this.p=pr;49   }50   public void run(){    51    while(true){52     p.set("BMW");53    }54   }  55 }56 //消费者57 class Consumer implements Runnable{58   private Product p;59   public Consumer(Product pr){60     this.p=pr;61   }  62   public void run(){    63     while(true){64     p.out();65     }66   }67 }

 

使用JDK5.0新特性改进后的代码

 1 /*JDK5.0后增加了Lock 和Condition新类特性来取代 同步和锁的繁琐操作 */ 2 public class ProducerConsumerNew { 3  4   public static void main(String[] args) { 5      6     Product pro=new Product(); 7      8    new Thread(new Producter(pro)).start();     9    new Thread(new Consumer(pro)).start();10    new Thread(new Producter(pro)).start();11    new Thread(new Consumer(pro)).start();12     13   }14 15 }16 class ProductNew{  17   private String name;18   private int No=1;19   boolean flag=false;20   21   private Lock lock=new ReentrantLock();22   private Condition con1=lock.newCondition();23   private Condition con2=lock.newCondition();24   25   public void set(String name){26     27     while(flag)28       try {29         lock.lock();30         con1.wait();31       } catch (InterruptedException e) {32         e.printStackTrace();33       }finally{34         lock.unlock();35       }36      this.name=name+"---"+this.No++; 37      System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");38       39      this.flag=true;40      con2.signal();41   }42   43   public void out(){    44     while(!this.flag)45       try {46         lock.lock();47         con2.wait();48       } catch (InterruptedException e) {49         e.printStackTrace();50       }finally{51         lock.unlock();52         con1.signal();53       }    54     System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");55     56     this.flag=false;57   }58 }59 //生产者60 class ProducterNew implements Runnable{61   private ProductNew p;62   public ProducterNew(ProductNew pr){63     this.p=pr;64   }65   public void run(){66    while(true){67     p.set("BMW");68    }69   }  70 }71 //消费者72 class ConsumerNew implements Runnable{73   private ProductNew p;74   public ConsumerNew(ProductNew pr){75     this.p=pr;76   }  77   public void run(){78     while(true)79     p.out();80   }81 }  

  

2、停止线程、及其会出现的问题、及解决的办法    

停止线程思路:开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以让run()方法结束,线程即结束。

特殊情况:当线程处于冻结状态(wait()),就不会读取到标记,那么线程就不会结束。

解决办法:当没有指定的方式让冻结的线程恢复到运行状态时,需要用Interrupt()方法强制清除冻结状态,再用操作标记让线程结束 

 

一个简单的代码例子

 1 public class ThreadStop { 2  3   public static void main(String[] args) { 4      5     ThreadTt tt=new ThreadTt(); 6      7     Thread th1=new Thread(tt); 8     Thread th2=new Thread(tt); 9     th1.start();10     th2.start();11     int count=0;12     while(true){13       if(++count>60){   //循环来控制线程的结束14         th1.interrupt(); //强制清除线程冻结状态15         th2.interrupt();16         break;17       }18       System.out.println(Thread.currentThread().getName()+"....run---"+count);19     }   20     System.out.println(Thread.currentThread().getName()+"....over");21   }22 }23 class ThreadTt implements Runnable{24   25  boolean flag=true;26  Lock lock=new ReentrantLock();27  Condition con=lock.newCondition();28   public synchronized void run() {29     30     while(flag){31       try {32         wait();    //用这个方法让线程处于冻结状态33       } catch (InterruptedException e) {34         System.out.println(e.getStackTrace());35         flag=false;36       }37     System.out.println(Thread.currentThread().getName()+"...run");38     }39   }40 }

 

 

3、守护线程及几个Thread的方法

 

守护线程/用户线程:通俗而言为”后台进程”,当前台进程都结束时,后台进程自动结束;当正在运行的线程都是守护线程时,JVM自动退出。     

 

setDaemon()方法设置守护线程,该方法必须在启动线程前调用

 

 

Join()方法  特点:当A线程执行到了B线程的jion()方法是,A就会等待,等B线程都执行完以后,A才会执行。Jion可以用来临时加入线程执行    线程抢夺cpu执行权

 

ToString()方法

 

setPriority()方法 更改线程的优先级,优先级代表抢夺资源的频率高低

 

Yield()方法  暂停当前线程的执行,去执行其它线程

 

4、工作中线程的常见写法(用到内部类)

不多说,看代码

 1 public class ThreadStand { 2  3   public static void main(String[] args) { 4   //工作中多线程的常见写法,构建内部类 5     new Thread(){ 6       public void run(){ 7         for(int i=0;i<100;i++) 8           System.out.println(Thread.currentThread().getName()+"....run...."+i); 9       }10     }.start();11     12     for(int i=0;i<100;i++)13       System.out.println(Thread.currentThread().getName()+"....run...."+i);14     15     //构造内部类16     Runnable rn= new Runnable(){17       public void run() {18         for(int i=0;i<100;i++)19           System.out.println(Thread.currentThread().getName()+"....run...."+i);        20       }21     }; 22     new Thread(rn).start();  23   }24 }

       

       初学者难免错误,欢迎评判指教,持续更正ing...........

 

ASP.Net+Android+IOS开发  、Net培训、期待与您交流!