/*
一个生产线程,一个消费线程,不存在安全问题
当定义两个生产线程和消费线程的时候,出现了生产两次消费一次,生产一次消费两次的安全问题
出现问题的原因是:线程被唤醒之后没有回去判断标记,直接执行后边的代码
解决方式:让线程被唤醒之后不是直接执行后边的代码,而是回去判断标记
把if改成while
但是这样又会出现新的问题:把if改为while之后,出现了死锁,原因是唤醒的是本方线程,
导致所有线程全部等待,notify唤醒的是任意的线程,不能保证唤醒的是对方线程(生产对应消费)
解决方式:把notify改为notifyAll
但是这样又降低了效率,把不该唤醒的线程也唤醒了,进一步优化的解决方式会在以后的博客中介绍,在jdk1.5之前只能用这种方式解决这个方法...
*/
//描述产品
class Product{
private String name;
private int count;
private boolean flag;
//生产产品的功能
public synchronized void produce(String name){
//if(flag){//把if改为while
while(flag){
try{wait();}catch(InterruptedException e){e.printStackTrace();}
}
this.name = name+"..."+count;
System.out.println(Thread.currentThread().getName()+"生产了..."+this.name);
count++;
flag = true;
notifyAll();
}
//生产的时候不能消费,消费的时候不能生产,否则会出现安全问题
//消费产品的功能
public synchronized void consume(){
while(!flag){
try{wait();}catch(InterruptedException e){e.printStackTrace();}
}
System.out.println(Thread.currentThread().getName()+"...消费了..."+this.name);
flag = false;
notifyAll();
}
}
//生产任务
class Producer implements Runnable{
private Product pro;
public Producer(Product pro){
this.pro = pro;
}
public void run(){
while(true){
pro.produce("笔记本");
}
}
}
//消费任务
class Consumer implements Runnable{
private Product pro;
public Consumer(Product pro){
this.pro = pro;
}
public void run(){
while(true){
pro.consume();
}
}
}
class test{
public static void main(String[] args){
Product pro = new Product();
Producer producer = new Producer(pro);
Consumer consumer = new Consumer(pro);
Thread t0 = new Thread(producer);
Thread t1 = new Thread(producer);
Thread t2 = new Thread(consumer);
Thread t3 = new Thread(consumer);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
Java——生产者消费者中多线程安全问题
最新推荐文章于 2024-02-10 12:15:21 发布