多線程生產者只有多個生產者,多個消費者!這裏不講基礎的知識。java
代碼以下多線程
package Thread; class Resource { private String name; private int count=0; private boolean flag=false; public synchronized void set(String name){ while (flag){ //這裏必須用循環由於要讓每一個生產者都知道本身要不要生產。若是不加就可能出現生產者喚醒生產者,而後連續兩次生產。 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name=name+"--"+count++; System.out.println(Thread.currentThread().getName()+"...生產者..."+this.name); flag=true; this.notifyAll();//這裏也要用notifyAll()不然,可能形成全部的線程都在等待。 } public synchronized void out(){ while(!flag){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } 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(); } } } public class ProducterConsumerDemo { 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(); } }
這是運行的結果。能夠看出都是一個生產一個消費。ide
然而當jdk1.5以後,咱們能夠用一些新特性去解決這個問題。java.util.concurrent.locks包下面的Lock接口,Condition接口。
this
這裏其實Lock能夠代替synchronized,而Condition所替代監視器。線程
這裏並且Lock能夠產生多個Condition監視器。對象
class Resource{ private int count=0; private String name; private boolean flag=false; Lock lock=new ReentrantLock(); Condition pro_condition=lock.newCondition();//這裏是生產者的監視器 Condition con_condition=lock.newCondition();//這裏是消費者的監視器 public void set(String name){ while(true) { try { lock.lock();//這裏至關於代替了synchroinzed 代碼塊。這不過更人性,直接說上鎖。 while (flag) { try { pro_condition.await();//可是應爲await 會拋出異常但不是放鎖,因此就必須在finally裏釋放鎖 } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name + "--" + count++; System.out.println(Thread.currentThread().getName() + "-生產者.." + this.name); flag = true;//生產完成後將標誌置爲真! con_condition.signal(); //等價於this.notifyAll這裏鎖匙this對象 } catch (Exception e) { } finally { lock.unlock();//可是應爲await 會拋出異常但不是放鎖,因此就必須在finally裏釋放鎖 } } } public void out(){ while(true) { lock.lock(); try { while (flag == false) { con_condition.wait();//即便有消費者線程被喚醒也必須判斷flag的標誌 } System.out.println(Thread.currentThread().getName() + "-消費者.." + name); flag = false; pro_condition.signal(); } catch (Exception e) { } finally { lock.unlock(); } } } } class Producer implements Runnable{ private Resource resource; Producer(Resource resource){ this.resource=resource; } public void run() { resource.set("商品"); } } class Consumer implements Runnable{ private Resource resource; Consumer(Resource resource){ this.resource=resource; } public void run() { resource.out(); } } public class ProducterConsumerDemo{ public static void main(String[] args) { Resource resource=new Resource(); Producer producer=new Producer(resource); Consumer consumer=new Consumer(resource); Thread p1=new Thread(producer); Thread p2=new Thread(producer); Thread c1=new Thread(consumer); Thread c2=new Thread(consumer); p1.start(); p2.start(); c1.start(); c2.start(); } }
這裏能夠看出,兩個Condition對象,能夠不用notifyAll()。生產者的鎖須要消費者去打開,消費者能夠用生產者打開。
blog