java中的生产者和消费者的问题

时间:2023-03-09 22:38:47
java中的生产者和消费者的问题

1----使用Java.util.concurrent.locks包中的lock接口取代synchronized,通过ReentrantLock这个已经实现Lock接口的类,

创建ReentrantLock对象lock(private final ReentrantLock lock = new ReentrantLock(); ) ,并通过使用这个对象中的lock()方法让线程获得锁(lock.lock(););

使用unlock();在退出代码块块时释放锁(lock.unlock();),

2----其中while(flag)解决了if(flag)存在的重复生产,使得消费者丢失对其中被覆盖的数据(烧鸡)的读取.但是while会导致死锁,会出现全部线程都被休眠的情况,此时可以将notify ()修改为notifyAll()使得程序被全部唤醒,间接实现相互唤醒,但是由于对同类线程的唤醒时没有意义的,此时,程序的效率降低.

3---解决上一个问题的方法为:使用Java.util.concurrent.locks中的Condition接口,通过对同一个锁创建不同的Condition实例,并使用不同实例调用其各自的await()和signal()方法实现对t0 t1和t2 t3这2组线程的冻结和唤醒管理.从而不再需要每次都全部唤醒造成的效率降低的问题.

 /*
需求:生产者---->消费者
资源:烤鸭一只
每生产一只,就消费一zhi
*/
import java.util.concurrent.locks.*;
class Resource
{
private String name;
private int count=0;
private boolean flag=false;
private final ReentrantLock lock = new ReentrantLock();
final Condition cond1 = lock.newCondition();
final Condition cond2 = lock.newCondition();
public void make(String name)
{
lock.lock();
while(flag)
try
{
cond1.await();
}
catch (InterruptedException e)
{
} this.name = name;
count++;
flag=true;
cond2.signal();
System.out.println(Thread.currentThread().getName()+"生产者..."+name+count);
lock.unlock();
}
public void out()
{
lock.lock();
while(!flag)
try
{
cond2.await();
}
catch (InterruptedException e)
{
}
System.out.println(Thread.currentThread().getName()+"消费者......."+count);
flag = false;
cond1.signal();
lock.unlock();
} }
class Producer implements Runnable
{
Resource r = new Resource();
Producer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.make("烤鸭");
}
}
class Customer implements Runnable
{
Resource r = new Resource();
Customer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
r.out();
}
}
class ProducerCustomer
{
public static void main(String[] args)
{
//建立资源类
Resource r = new Resource();
//建立任务对象
Producer pro = new Producer(r);
Customer cus = new Customer(r);
//建立线程
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(cus);
Thread t3 = new Thread(cus);
//开启线程
t0.start();
t1.start();
t2.start();
t3.start(); }
}