ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java学习之线程通信(多线程(synchronized))

2019-12-23 11:51:03  阅读:169  来源: 互联网

标签:Java name synchronized Thread private flag 线程 多线程 out


分析线程经典案例生产者消费者

 1 /**
 2 共享数据
 3 */
 4 class Resource
 5 {
 6     private String name;
 7     private int count=1;
 8     private boolean flag=false;
 9     
10     public synchronized void set(String name)
11     {    
12         if(flag)
13             try{this.wait();}catch(InterruptedException e){}
14         this.name=name+count;
15         count++;
16         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
17         flag = true;
18         notify();
19     }
20     
21     public synchronized void out() 
22     {
23         if(!flag)
24             try{this.wait();}catch(InterruptedException e){}
25         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
26         flag = false;
27         notify();
28     }
29 }
30 
31 //定义线程任务(生产者线程)
32 class Producer implements Runnable
33 {
34     private Resource r;
35     
36     Producer(Resource r)
37     {
38         this.r=r;
39     }
40     public void run()
41     {
42         while(true)
43         {
44             r.set("商品");
45         }
46     }
47 }
48 //定义线程任务(消费者线程)
49 class Consumer implements Runnable
50 {
51     private Resource r;
52     
53     Consumer(Resource r)
54     {
55         this.r=r;
56     }
57     
58     public void run()
59     {
60         while(true)
61         {
62             r.out();
63         }
64     }
65 }
66 
67 class ProducerConsumerDemo
68 {
69     public static void main(String[] args)
70     {
71         //实例化共享资源
72         Resource r = new Resource();
73         //实例化线程任务,指定共享资源
74         Producer p=new Producer(r);
75         Consumer c=new Consumer(r);
76         //实例化线程,指定线程任务
77         Thread t0=new Thread(p);
78         Thread t1=new Thread(p);
79         Thread t2=new Thread(c);
80         Thread t3=new Thread(c);
81         //开启线程,执行线程任务中的run方法
82         t0.start();
83         t1.start();
84         t2.start();
85         t3.start();
86     }
87 }

运行结果:

 

 

结果分析:

 

那么怎么再判断flag呢?while

代码如下:

 1 class Resource
 2 {
 3     private String name;
 4     private int count=1;
 5     private boolean flag=false;
 6     
 7     public synchronized void set(String name) // 有两个线程t0 t1
 8     {    
 9         while(flag)
10             try{this.wait();}catch(InterruptedException e){}
11         this.name=name+count;
12         count++;
13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
14         flag = true;
15         notify();
16     }
17     
18     public synchronized void out() // 有两个线程t2 t3
19     {
20         while(!flag)
21             try{this.wait();}catch(InterruptedException e){}
22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
23         flag = false;
24         notify();
25     }
26 }

结果出现死锁:

 

结果分析:

通过分析,那能不能每次唤醒只唤醒对方线程(如生产者线程只唤醒消费者线程,消费者线程只唤醒生产者线程),查看Object对象方法中没有,但是有一个notifyAll()方法,实在不行就把所有阻塞线程(相同同步锁的线程)都唤醒。

 1 class Resource
 2 {
 3     private String name;
 4     private int count=1;
 5     private boolean flag=false;
 6     
 7     public synchronized void set(String name) // 有两个线程t0 t1
 8     {    
 9         while(flag)
10             try{this.wait();}catch(InterruptedException e){}
11         this.name=name+count;
12         count++;
13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
14         flag = true;
15         notifyAll();
16     }
17     
18     public synchronized void out() // 有两个线程t2 t3
19     {
20         while(!flag)
21             try{this.wait();}catch(InterruptedException e){}
22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
23         flag = false;
24         notifyAll();
25     }
26 }

结果:

 

这样就可以了。

总结:

if判断只能判断一次,如果执行等待方法,下次唤醒的线程获取执行权后(唤醒后的线程会从上次等待位置,向下执行)就不能再判断

while判断解决唤醒的线程获取执行权后无法判断

notify:只能唤醒任意一个线程,有可能会唤醒本方线程,while+notify会导致死锁

notifyAll:解决了死锁问题

 

标签:Java,name,synchronized,Thread,private,flag,线程,多线程,out
来源: https://www.cnblogs.com/WarBlog/p/12082961.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有