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