首页 > 学院 > 开发设计 > 正文

黑马程序员系列第二篇多线程(2)

2019-11-14 15:07:36
字体:
来源:转载
供稿:网友

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

 

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

 

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

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

代码示例:

public class PRoducerConsumer {//需求:生产和消费行为依次进行。     设置产品为BMW   设置生产者和消费者线程各两个    public static void main(String[] args) {                 Product pro=new Product();                 new Thread(new Producter(pro)).start();               new Thread(new Consumer(pro)).start();        new Thread(new Producter(pro)).start();        new Thread(new Consumer(pro)).start();    }}class Product{        private String name;    private int No=1;    boolean flag=false;        public synchronized void set(String names){        while(flag)            try {                 this.wait();//等待状态                            } catch (InterruptedException e) {                e.printStackTrace();            }                  this.name=names+"---"+this.No++;              System.out.println(this.name+"---被"+Thread.currentThread().getName()+"生产");                            flag=true;                this.notifyAll();//唤醒所有线程    }        public synchronized void out(){        while(!flag)            try {                this.wait();//等待状态            } catch (InterruptedException e) {                e.printStackTrace();            }                System.out.println(this.name+"---被"+Thread.currentThread().getName()+"消费了-------");                       flag=false;               this.notifyAll();//唤醒所有线程    }}//生产者class Producter implements Runnable{    private Product p;    public Producter(Product pr){        this.p=pr;    }    public void run(){              while(true){        p.set("BMW");      }    }    }//消费者class Consumer implements Runnable{    private Product p;    public Consumer(Product pr){        this.p=pr;    }        public void run(){                while(true){        p.out();        }    }}

 

 

 

使用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培训、期待与您交流!

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表