1.5之前的写法.
/* 生产者消费者 两个线程生产,两个线程消费. 而且要是生产一个消费一个. 主要问题:使用notifyAll会唤醒本方线程,这个问题要lock和conditions来处理. 如果不用notifyAll,只用notify所有线程都会wait. */ class TestMain { public static void main(String[] args) { Resource res = new Resource(); Producer pro = new Producer(res); Consumer con = new Consumer(res); Thread t1 = new Thread(res); Thread t2 = new Thread(pro); Thread t3 = new Thread(res); Thread t4 = new Thread(pro); t1.start(); t2.start(); t3.start(); t4.start(); } } class Resource { private String name; private int count=1; private boolean flag =false; public synchronized void set(String name){ if(flag){ try{ wait();//线程会停在这里,但是当线程被唤醒的时候,一样要循环判断标记.所以if要改成while }catch(Exception e){ //如果出异常,方法结束,就出了synchronized代码块锁也有释放了.这点不像lock.nulock().nulock是一定要执行的,出了异常,方法结束也是要执行的. } } this.name=name+"--"+count++; System.out.println(Thread.curentThread().getName()+"生产的"+this.name); flag=true; this.notify();//这里唤醒的时候可能唤醒的是本方线程,导致所有线程wait,所以要用 notifyAll() } public synchronized void out(){ if(!flag){ try{ wait(); }catch(Exception e){ // } } System.out.println(Thread.curentThread().getName()+"消费者"+this.name); flag=false; this.notify(); } } class Producer implements Runnable { private Resource res; Producer(Resource res){ this.res=res; } @Override public void run(){ while(true){ res.set("+商品+"); } } } class Consumer implements Runnable { private Resource res; Producer(Resource res){ this.res=res; } @Override public void run(){ while(true){ res.out(); } } }
1.5之后的写法
/* 生产与消费者 jdk1.5 之后的Lock与Condition 可以保证唤醒的是对方线程,可以唤醒对方一个,也可以是所有.主要看用的是signal与signalAll() */ class TestMain { public static void main(String[] args) { //要操作的数据,资源 Resource res = new Resource(); //两个生产,消费线程 Producer pro = new Producer(res); Resource res = new Resource(); Producer pro = new Producer(res); Consumer con = new Consumer(res); Thread t1 = new Thread(res); Thread t2 = new Thread(pro); Thread t3 = new Thread(res); Thread t4 = new Thread(pro); t1.start(); t2.start(); t3.start(); t4.start(); } } /* 资源类,里面的要操作的数据,操作数据的方法,标记,锁,Condition. */ class Resource { private String name; private int count=1; private boolean flag =false; //1.5之后lock代替了,syschronized private Lock lock =new ReentrantLock(); //Condition 代替了Objcet里面的wait,notify,notifyAll private Condition condition1=lock.newCondition(); //用来分组线程,本方只唤醒对方线程的操作. private Condition condition2=lock.newCodition(); //去掉了synchronized关键字 public void set(String name){ while(flag){ try{ condition1.await(); }catch(Exception e){ //这里一但出异常,因为还没有执行lock.unlock()会,所以方法结束但是锁还没有释放,所以一定要入finally里面去执行nulock(); } } this.name=name+"--"+count++; System.out.println(Thread.curentThread().getName()+"生产的"+this.name); flag=true; //condition.signalAll();//这样可能会唤醒本方线程.用signal()会全部等待. condition2.signal()//这样可以保证唤醒的是对方线程. lock.unlock(); } //去掉synchronized public void out(){ lock.loct(); try{ while(!flag){ condition2.await()//线程被唤醒后,一定要循环判断标记 } System.out.println(Thread.curentThread().getName()+"消费者"+this.name); flag=false; //condition.signalAll();//这里同样可能会唤醒本方的线程,要改的 condition2.signa(); }catch(InterrputedException e){ //await()的时候可会出异常,出了异常方法结束了,但也定要nulock() }finally{ lock.nulock(); } } } /* 生产者线程 */ class Producer implements Runnable { private Resource res; Producer(Resource res){ this.res=res; } @Override public void run(){ while(true){ res.set("+商品+"); } } } /* 消费者线程 */ class Consumer implements Runnable { private Resource res; Producer(Resource res){ this.res=res; } @Override public void run(){ while(true){ res.out(); } } }