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(); } }}
posted on 2016-03-23 22:38 阅读( ...) 评论( ...)