以下讲解Lock线程同步通信,也是比synchronized强大的一个功能点
先看一个常规的案例:
用户类
public class Person { public void eat(){ for(int i=0;i<3;i++){ System.out.println("eat..."); } } public void drink(){ for(int i=0;i<3;i++){ System.out.println("drink..."); } } public void play(){ for(int i=0;i<3;i++){ System.out.println("play..."); } } }
public class LockConditionTest { public static void main(String[] args) { final Person person = new Person(); new Thread( new Runnable() { @Override public void run() { for(int i=0;i<5;i++){ person.eat(); } } } ) .start(); new Thread( new Runnable() { @Override public void run() { for(int i=0;i<5;i++){ person.drink(); } } } ) .start(); for(int i=0;i<10;i++){ person.play(); } } }
结果输出:
eat...
eat...
play...
play...
play...
play...
play...
play...
play...
drink...
drink...
play...
play...
play...
play...
以上案例为传统线程调用,打印的结果也是有cpu随机调度输出
现在的需求是:person 吃喝玩方法要有顺序性调用,阻止cpu随机调度输出
参考以下案例(加入Lock实现同步通信):
public class Person { Lock lock = new ReentrantLock(); Condition condition1 = lock.newCondition(); Condition condition2 = lock.newCondition(); Condition condition3 = lock.newCondition(); private int shouldSub = 1; public void eat(){ lock.lock(); try{ while(shouldSub!=1){ //是1的时候执行 不是1的时候等待 try { condition1.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int i=0;i<3;i++){ System.out.println("eat..."); } shouldSub=2; condition2.signal(); // 1 执行完之后 通知2执行 }finally{ System.out.println("======================="); lock.unlock(); } } public void drink(){ lock.lock(); try{ while(shouldSub!=2){ //是2的时候执行 不是2的时候等待 try { condition2.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int i=0;i<3;i++){ System.out.println("drink..."); } shouldSub = 3; condition3.signal();// 2 执行完之后 通知3执行 }finally{ System.out.println("======================="); lock.unlock(); } } public void play(){ lock.lock(); try{ while(shouldSub!=3){ //是3的时候执行 不是3的时候等待 try { condition3.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int i=0;i<3;i++){ System.out.println("play..."); } shouldSub = 1; condition1.signal();// 3 执行完之后 通知1执行 }finally{ System.out.println("======================="); lock.unlock(); } } }
public class LockConditionTest { public static void main(String[] args) { final Person person = new Person(); new Thread( new Runnable() { @Override public void run() { for(int i=0;i<5;i++){ person.eat(); } } } ) .start(); new Thread( new Runnable() { @Override public void run() { for(int i=0;i<5;i++){ person.drink(); } } } ) .start(); for(int i=0;i<5;i++){ person.play(); } } }
结果输出:
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================