码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-11-10 22:32:55      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:

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

 

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

标签:

原文地址:http://www.cnblogs.com/blueFlowers/p/4953573.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!