需求:java
input 設置resource , resource爲name和sex,output輸出resource優化
代碼:this
package com.lee.juc.comm; public class ResourceDemo_01 { public static void main(String[] args) { Resource_01 r = new Resource_01(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } //資源 class Resource_01{ public String name; public String sex; } //生產者 class Input implements Runnable{ Resource_01 r; public Input(Resource_01 r) { this.r = r; } public void run() { int x = 0 ; while(true) { if(x==0) { r.name = "lee"; r.sex = "male"; }else { r.name = "迪"; r.sex = "女"; } x = (x+1)%2; } } } //消費者 class Output implements Runnable{ Resource_01 r; public Output(Resource_01 r) { this.r = r; } public void run() { while(true) { System.out.println(r.name+"...."+r.sex); } } }
結果:spa
緣由:input 設置了lee male後 又設置了name = 迪,sex尚未設置,output就輸出了。線程
解決方法:input和output用同一個鎖,只有輸入完成後output才能輸出,code
output輸出完成後,input才能輸入對象
解決代碼:資源
package com.lee.juc.comm; public class ResourceDemo_01 { public static void main(String[] args) { Resource_01 r = new Resource_01(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } //資源 class Resource_01{ public String name; public String sex; } //生產者 class Input implements Runnable{ Resource_01 r; public Input(Resource_01 r) { this.r = r; } public void run() { int x = 0 ; while(true) { synchronized (r) { if(x==0) { r.name = "lee"; r.sex = "male"; }else { r.name = "迪"; r.sex = "女"; } x = (x+1)%2; } } } } //消費者 class Output implements Runnable{ Resource_01 r; public Output(Resource_01 r) { this.r = r; } public void run() { while(true) { synchronized (r) { System.out.println(r.name+"...."+r.sex); } } } }
結果:get
問題: input了一個資源,卻output多個。input
一、這些方法都是Object的方法:
wait 讓線程處於凍結狀態,被wait的線程會被存儲在線程池中
notify 喚醒線程池中任意一個線程
notifyAll 喚醒線程池中的全部線程
二、代碼
package com.lee.juc.comm; public class ResourceDemo_02 { public static void main(String[] args) { Resource_02 r = new Resource_02(); Input_02 in = new Input_02(r); Output_02 out = new Output_02(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } //資源 class Resource_02{ public String name; public String sex; public boolean flag = false;//沒有定義name和sex } //生產者 class Input_02 implements Runnable{ Resource_02 r; public Input_02(Resource_02 r) { this.r = r; } public void run() { int x = 0 ; while(true) { synchronized (r) { if(r.flag==true) { try {r.wait();} catch (InterruptedException e) {e.printStackTrace();} }else { if(x==0) { r.name = "lee"; r.sex = "male"; }else { r.name = "迪"; r.sex = "女"; } x = (x+1)%2; r.flag=true; r.notify(); } } } } } //消費者 class Output_02 implements Runnable{ Resource_02 r; public Output_02(Resource_02 r) { this.r = r; } public void run() { while(true) { synchronized (r) { if(r.flag==false) { try {r.wait();} catch (InterruptedException e) {e.printStackTrace();} }else { System.out.println(r.name+"...."+r.sex); r.flag=false; r.notify(); } } } } }
三、結果:
三、代碼優化
package com.lee.juc.comm; public class ResourceDemo_03 { public static void main(String[] args) { Resource_03 r = new Resource_03(); Input_03 in = new Input_03(r); Output_03 out = new Output_03(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } //資源 class Resource_03{ private String name; private String sex; private boolean flag = false;//沒有定義name和sex public synchronized void set(String name,String sex) { if(flag) try {this.wait();} catch (InterruptedException e) {e.printStackTrace();} this.name = name; this.sex = sex; flag=true; this.notify(); } public synchronized void out() { if(!flag) try {this.wait();} catch (InterruptedException e) {e.printStackTrace();} System.out.println(name+"...+++..."+sex); flag=false; notify(); } } //生產者 class Input_03 implements Runnable{ Resource_03 r; public Input_03(Resource_03 r) { this.r = r; } public void run() { int x = 0 ; while(true) { if(x==0) { r.set("lee", "male"); }else { r.set("迪", "女"); } x = (x+1)%2; } } } //消費者 class Output_03 implements Runnable{ Resource_03 r; public Output_03(Resource_03 r) { this.r = r; } public void run() { while(true) { r.out(); } } }
一、流程圖
二、代碼
package com.lee.juc.comm; public class ProducerConsumerDemo_01 { public static void main(String[] args) { Resource_01 r = new Resource_01(); Producer_01 pro = new Producer_01(r); Consumer_01 con = new Consumer_01(r); Thread t0 = new Thread(pro); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); Thread t3 = new Thread(con); t0.start(); t1.start(); t2.start(); t3.start(); } } class Resource_01{ private String name; private Integer count=1; private boolean flag = false; public synchronized void set(String name) { while(flag)//================ try {this.wait();} catch (InterruptedException e) {e.printStackTrace();} this.name = name+""+count; count++; System.out.println(Thread.currentThread().getName()+"...生產者..."+this.name); this.flag=true; this.notifyAll();//=============== } public synchronized void out() { while(!flag)//============= try {this.wait();} catch (InterruptedException e) {e.printStackTrace();} System.out.println(Thread.currentThread().getName()+"...消費者........."+this.name); this.flag=false; this.notifyAll();//=================== } } class Producer_01 implements Runnable{ Resource_01 r; public Producer_01(Resource_01 r) { this.r = r; } public void run() { while(true) { r.set("烤鴨"); } } } class Consumer_01 implements Runnable{ Resource_01 r; public Consumer_01(Resource_01 r) { this.r = r; } public void run() { while(true) { r.out(); } } }
二、結果
一、Lock
實現提供了比使用 synchronized
方法和語句可得到的更普遍的鎖定操做。此實現容許更靈活的結構,能夠具備差異很大的屬性,能夠支持多個相關的 Condition
對象。
簡單的說Lock便是對synchronized的拓展。
二、Condition
將 Object
監視器方法(wait
、notify
和 notifyAll
)分解成大相徑庭的對象,以便經過將這些對象與任意 Lock
實現組合使用,爲每一個對象提供多個等待 set(wait-set)。其中,Lock
替代了 synchronized
方法和語句的使用,Condition
替代了 Object 監視器方法的使用。
代碼:
package com.lee.juc.comm; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockDemo { public static void main(String[] args) { Resource_05 r = new Resource_05(); Producer_02 pro = new Producer_02(r); Consumer_02 con = new Consumer_02(r); Thread t0 = new Thread(pro); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); Thread t3 = new Thread(con); t0.start(); t1.start(); t2.start(); t3.start(); } } class Resource_05{ private String name; private Integer count=1; private boolean flag = false; Lock lock = new ReentrantLock(); Condition producter_con = lock.newCondition(); Condition consumer_con = lock.newCondition(); public void set(String name) { lock.lock(); try { while(flag) try {producter_con.await();} catch (InterruptedException e) {e.printStackTrace();} this.name = name+""+count; count++; System.out.println(Thread.currentThread().getName()+"...生產者..."+this.name); this.flag=true; consumer_con.signal(); } finally { lock.unlock(); } } public void out() { lock.lock(); try { while(!flag) try {consumer_con.await();} catch (InterruptedException e) {e.printStackTrace();} System.out.println(Thread.currentThread().getName()+"...消費者........."+this.name); this.flag=false; producter_con.signal(); } finally { lock.unlock(); } } } class Producer_02 implements Runnable{ Resource_05 r; public Producer_02(Resource_05 r) { this.r = r; } public void run() { while(true) { r.set("烤鴨"); } } } class Consumer_02 implements Runnable{ Resource_05 r; public Consumer_02(Resource_05 r) { this.r = r; } public void run() { while(true) { r.out(); } } }