生产者消费者问题

Synchronized 实现生产者消费者:(隐式的加锁)

class ProducerConsumerDemo 

{

public static void main(String[] args) 

{

Resource r = new Resource();

 

Producer pro = new Producer(r);

Consumer con = new Consumer(r);

 

Thread t1 = new Thread(pro);

Thread t2 = new Thread(pro);

Thread t3 = new Thread(con);

Thread t4 = new Thread(con);

 

t1.start();

t2.start();

t3.start();

t4.start();

 

}

}

 

/*

对于多个生产者和消费者。

为什么要定义while判断标记。

原因:让被唤醒的线程再一次判断标记。

 

 

为什么定义notifyAll

因为需要唤醒对方线程。

因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。

 

*/

 

 

class Resource

{

private String name;

private int count = 1;

private boolean flag = false;

//  t1    t2

public synchronized void set(String name)

{

while(flag)

try{this.wait();}catch(Exception e){}//t1(放弃资格)  t2(获取资格)

this.name = name+"--"+count++;

 

System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);

flag = true;

this.notifyAll();

}

 

 

//  t3   t4  

public synchronized void out()

{

while(!flag)

try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)

System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);

flag = false;

this.notifyAll();

}

}

 

class Producer implements Runnable

{

private Resource res;

 

Producer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

res.set("+商品+");

}

}

}

 

class Consumer implements Runnable

{

private Resource res;

 

Consumer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

res.out();

}

}

}

 

Lock 实现生产者消费者:(JDK1.5后出现了Lock:显式的加锁)

import java.util.concurrent.locks.*;

 

class ProducerConsumerDemo2 

{

public static void main(String[] args) 

{

Resource r = new Resource();

 

Producer pro = new Producer(r);

Consumer con = new Consumer(r);

 

Thread t1 = new Thread(pro);

Thread t2 = new Thread(pro);

Thread t3 = new Thread(con);

Thread t4 = new Thread(con);

 

t1.start();

t2.start();

t3.start();

t4.start();

 

}

}

 

/*

JDK1.5 中提供了多线程升级解决方案。

将同步Synchronized替换成现实Lock操作。

Object中的waitnotify notifyAll,替换了Condition对象。

该对象可以Lock锁 进行获取。

该示例中,实现了本方只唤醒对方操作。

 

Lock:替代了Synchronized

lock 

unlock

newCondition()

 

Condition:替代了Object wait notify notifyAll

await();

signal();

signalAll();

*/

class Resource

{

private String name;

private int count = 1;

private boolean flag = false;

//  t1    t2

private Lock lock = new ReentrantLock();

 

private Condition condition_pro = lock.newCondition();

private Condition condition_con = lock.newCondition();

 

 

 

public  void set(String name)throws InterruptedException

{

lock.lock();

try

{

while(flag)

condition_pro.await();//t1,t2

this.name = name+"--"+count++;

 

System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);

flag = true;

condition_con.signal();

}

finally

{

lock.unlock();//释放锁的动作一定要执行。

}

}

 

 

//  t3   t4  

public  void out()throws InterruptedException

{

lock.lock();

try

{

while(!flag)

condition_con.await();

System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);

flag = false;

condition_pro.signal();

}

finally

{

lock.unlock();

}

}

}

 

class Producer implements Runnable

{

private Resource res;

 

Producer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

try

{

res.set("+商品+");

}

catch (InterruptedException e)

{

}

}

}

}

 

class Consumer implements Runnable

{

private Resource res;

 

Consumer(Resource res)

{

this.res = res;

}

public void run()

{

while(true)

{

try

{

res.out();

}

catch (InterruptedException e)

{

}

}

}

}

Synchronized在同步代码块执行完毕或者出现异常时,会自动的释放锁。而Lock在出现异常时不会自动释放锁,所以会写成try(处理代码)finally(lock.unlock)格式防止出现异常时不释放锁的情况。但是在这里出现异常的地方是await(),如果在该地方try.{}..catch(){}一下,就不用外层的try{}..finally{}了,因为异常捕获后会直接往下执行,从而释放锁:如下代码:

package base;

 

 

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.*;

public class ProducerConsumerDemo2 {

 

public static void main(String[] args) {

Resource resource=new Resource();

Input input=new Input(resource);

Output output=new Output(resource);

Thread thread1=new Thread(input);

Thread thread2=new Thread(input);

Thread thread3=new Thread(output);

Thread thread4=new Thread(output);

thread1.start();

thread2.start();

thread3.start();

thread4.start();

}

 

}

class Resource{  

private String name;

private int count=1;

private boolean flag=false;

private Lock lock=new ReentrantLock();

private Condition condition_pro=lock.newCondition(); 

private Condition condition_con=lock.newCondition(); 

public  void set(String name)

{

lock.lock();

while(flag){

try {

condition_pro.await();

throw new InterruptedException();

catch (InterruptedException e) {

//e.printStackTrace();

}

}

this.name=name+"编号"+(count++);

System.out.println(Thread.currentThread().getName()+"生产"+this.name);

flag=true;

condition_con.signal();

lock.unlock();

 

}

public  void out()

{

lock.lock();

while(!flag){

try {

condition_con.await();

throw new InterruptedException();

catch (InterruptedException e) {

//e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"....消费..."+this.name);

flag=false;

condition_pro.signal();

}

}

class Input implements Runnable{

private Resource res;

public Input(Resource res){

this.res=res;

}

public void run(){

while(true){

res.set("商品");

 

}

}

 

}

class Output implements Runnable{

private Resource res;

public Output(Resource res){

this.res=res;

}

public void run(){

while(true){

res.out();

}

}

}

但是如果,await()处不处理异常而是像上面的抛异常给上级,那么就需要try{}...finally{},因为出现异常后,下面的代码将不会执行,锁将不会被释放

一般为安全起见,写第一种方法。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值