实例
模仿生产者和消费者的模式
先来个两个线程的
class ProducerConsumerDemo { public static void main(String[] args) { Res r=new Res(); Pro in=new Pro(r); Cou out=new Cou(r); Thread t1=new Thread(in); Thread t2=new Thread(out); t1.start(); t2.start(); } } class Res { private String name; private int count=1; private boolean flag=false; public synchronized void set(String name) { if(flag) try{wait();}catch(Exception e){} this.name=name+"---"+count++; System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name); flag=true; this.notify(); } public synchronized void out() { if(!flag) try{wait();}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"消费者"+this.name); flag=false; this.notify(); } } class Pro implements Runnable { private Res r; Pro(Res r) { this.r=r; } public void run() { while(true) { r.set("--商品--"); } } } class Cou implements Runnable { private Res r; Cou(Res r) { this.r=r; } public void run() { while(true) { r.out(); } } }
这样就OK了
下面就试试四个线程的,两个线程生产,两个线程消费;
class ProducerConsumerDemo { public static void main(String[] args) { Res r=new Res(); Pro in=new Pro(r); Cou out=new Cou(r); Thread t1=new Thread(in); Thread t2=new Thread(in); Thread t3=new Thread(out); Thread t4=new Thread(out); t1.start(); t2.start(); t3.start(); t4.start(); } } class Res { private String name; private int count=1; private boolean flag=false; public synchronized void set(String name) { if(flag) try{wait();}catch(Exception e){} this.name=name+"---"+count++; System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name); flag=true; this.notify(); } public synchronized void out() { if(!flag) try{wait();}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"消费者"+this.name); flag=false; this.notify(); } } class Pro implements Runnable { private Res r; Pro(Res r) { this.r=r; } public void run() { while(true) { r.set("--商品--"); } } } class Cou implements Runnable { private Res r; Cou(Res r) { this.r=r; } public void run() { while(true) { r.out(); } } }
但结果是多生产少消费,并不是我们想要的一生产一消费;
改良代码
class ProducerConsumerDemo { public static void main(String[] args) { Res r=new Res(); Pro in=new Pro(r); Cou out=new Cou(r); Thread t1=new Thread(in); Thread t2=new Thread(in); Thread t3=new Thread(out); Thread t4=new Thread(out); t1.start(); t2.start(); t3.start(); t4.start(); } } class Res { private String name; private int count=1; private boolean flag=false; public synchronized void set(String name) { while(flag) try{wait();}catch(Exception e){} this.name=name+"---"+count++; System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name); flag=true; this.notifyAll(); } public synchronized void out() { while(!flag) try{wait();}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"消费者"+this.name); flag=false; this.notifyAll(); } } class Pro implements Runnable { private Res r; Pro(Res r) { this.r=r; } public void run() { while(true) { r.set("--商品--"); } } } class Cou implements Runnable { private Res r; Cou(Res r) { this.r=r; } public void run() { while(true) { r.out(); } } }
对于多个生产者和消费者。
为什么要定义while判断标记。
原因:让被唤醒的线程在一次判断标记。
为什么定义notifyAll?
因为需要唤醒对方线程。
以为只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。
JDK新版中提供了多线程升级解决方案。
将同步Syschronized替换成现实Lock操作;
将Object中的wait, notify notifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。
实现了本方只唤醒对方的操作;
import java.util.concurrent.locks.*; class ProducerConsumerDemo2 { public static void main(String[] args) { Res r=new Res(); Pro in=new Pro(r); Cou out=new Cou(r); Thread t1=new Thread(in); Thread t2=new Thread(in); Thread t3=new Thread(out); Thread t4=new Thread(out); t1.start(); t2.start(); t3.start(); t4.start(); } } class Res { private String name; private int count=1; private boolean flag=false; private Lock lock=new ReentrantLock(); private Condition condition_in=lock.newCondition(); private Condition condition_out=lock.newCondition(); public void set(String name)throws InterruptedException { lock.lock(); try { while(flag) condition_in.await(); this.name=name+"---"+count++; System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name); flag=true; condition_out.signal(); } finally { lock.unlock();//解锁对象一定要执行 } } public void out()throws InterruptedException { lock.lock(); try { while(!flag) condition_out.await(); System.out.println(Thread.currentThread().getName()+"消费者"+this.name); flag=false; condition_in.signal(); } finally { lock.unlock(); } } } class Pro implements Runnable { private Res r; Pro(Res r) { this.r=r; } public void run() { try { while(true) { r.set("--商品--"); } } catch (InterruptedException e) { } } } class Cou implements Runnable { private Res r; Cou(Res r) { this.r=r; } public void run() { try { while(true) { r.out(); } } catch (InterruptedException e) { } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-26 20:05:54