生产者消费者中多线程安全问题(即线程间通信的安全问题)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生产者消费者中多线程安全问题(即线程间通信的安全问题)相关的知识,希望对你有一定的参考价值。

一个生产线程,一个消费线程,程序不存在安全问题

两个生产线程,两个消费线程,出现了生产两次,消费一次或者生产一次,消费两次的情况。
出现问题的原因是:线程被唤醒之后没有回去判断标记,直接继续执行后边的代码。
解决方式:让线程被唤醒之后不是直接执行后边的代码,而是回去判断标志,这个问题可以通过把if改成while实现。
          但这样做会出现死锁的状况,原因是唤醒了本方线程,导致所有线程全部等待。
          notify()唤醒的是任意一个线程,不能保证唤醒的是对方线程,这个问题可以将notify()改成notifyAll()来解决。
          这样做降低了程序的性能,但是能够保证不出错。

 1 class Product
 2 {
 3     private String name;
 4     private int count;
 5     private boolean flag;
 6     
 7     //生产产品的功能
 8     public synchronized void produce(String name)
 9     {
10         while (flag) 
11         //if (flag)
12         {
13             try{wait();}catch (InterruptedException e){e.printStackTrace();}
14         }
15         this.name = name+"..."+count;
16         System.out.println(Thread.currentThread().getName()+"***生产了***"+this.name);
17         count++;
18         flag = true;
19         notifyAll();
20         //notify();
21     }
22 
23     //消费产品的功能
24     public synchronized void consume()
25     {
26         while (!flag)
27         //if (flag)
28         {
29             try{wait();}catch (InterruptedException e){e.printStackTrace();}
30         }
31         System.out.println(Thread.currentThread().getName()+"---消费了---"+this.name);
32         flag = false;
33         notifyAll();
34         //notify();
35     }
36 }
37 
38 //生产任务
39 class Producer implements Runnable
40 {
41     private Product pro;
42     public Producer(Product pro)
43     {
44         this.pro = pro;
45     }
46     public void run()
47     {
48         while(true)
49         {
50             pro.produce("笔记本电脑");
51         }
52     }
53 }
54 
55 //消费任务
56 class Consumer implements Runnable
57 {
58     private Product pro;
59     public Consumer(Product pro)
60     {
61         this.pro = pro;
62     }
63     public void run()
64     {
65         while(true)
66         {
67             pro.consume();
68         }
69     }
70 }
71 
72 class Demo
73 {
74     public static void main(String[] args) 
75     {
76         Product pro = new Product();
77         
78         Producer producer = new Producer(pro);
79         Consumer consumer = new Consumer(pro);
80 
81         new Thread(producer,"生产线01").start();
82         new Thread(consumer,"消费者01").start();
83         new Thread(producer,"生产线02").start();
84         new Thread(consumer,"消费者02").start();
85     }
86 }

 

以上是关于生产者消费者中多线程安全问题(即线程间通信的安全问题)的主要内容,如果未能解决你的问题,请参考以下文章

线程间通信:等待唤醒机制

进程与线程

线程通信之生产者消费者模型

python 线程通信 生产者与消费者

python 线程通信 生产者与消费者

Linux线程安全