需求: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(); } } }