线程之间的同步通信
第一个线程循环3次,然后二个线程循环5次, 然后第三个线程循环8次, 这样执行50次。
一: 传统的wait(), notify(), notifyAll()
package com.cn.gbx; public class TheadConnection { public static void main(String[] args) { final Business business = new Business(); new Thread( new Runnable() { @Override public void run() { for (int i = 1; i <= 50; ++i) { business.sub1(i); } } } ).start(); new Thread( new Runnable() { @Override public void run() { for (int i = 1; i <= 50; ++i) { business.sub2(i); } } } ).start(); new Thread( new Runnable() { @Override public void run() { for (int i = 1; i <= 50; ++i) { business.sub3(i); } } } ).start(); } } class Business{ private int bShould = 0; public synchronized void sub1(int i) { System.out.println("sub1..." + bShould); while (bShould != 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 1; j <= 3; ++j) { System.out.println(Thread.currentThread().getName() + " sub1 Thread seq " + i + " looping " + j); } bShould = 1; this.notifyAll(); //一定要是notifyAll()否则会出现线程阻塞, 唤醒了其余两个的一个, //然后唤醒的那个不满足执行条件,然后就没有可以将其他可执行的线程激活的了而导致死锁 } public synchronized void sub2(int i) { System.out.println("sub2..." + bShould); while (bShould != 1) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for (int j = 1; j <= 5; ++j) { System.out.println(Thread.currentThread().getName() + " sub2 Thread seq " + i + " looping " + j); } bShould = 2; this.notifyAll(); } public synchronized void sub3(int i) { System.out.println("sub3..." + bShould); while (bShould != 2) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 1; j <= 8; ++j) { System.out.println(Thread.currentThread().getName() + " sub3 Thread seq " + i + " looping " + j); } bShould = 0; this.notifyAll(); } }
二:
通过Condition实现通信:
package com.cn.gbx; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class TheadConnection { public static void main(String[] args) { final Business business = new Business(); new Thread( new Runnable() { @Override public void run() { for (int i = 1; i <= 50; ++i) { business.sub1(i); } } } ).start(); new Thread( new Runnable() { @Override public void run() { for (int i = 1; i <= 50; ++i) { business.sub2(i); } } } ).start(); new Thread( new Runnable() { @Override public void run() { for (int i = 1; i <= 50; ++i) { business.sub3(i); } } } ).start(); } } class Business{ private int bShould = 0; Lock lock = new ReentrantLock(); Condition condition1 = lock.newCondition(); Condition condition2 = lock.newCondition(); Condition condition3 = lock.newCondition(); public void sub1(int i) { lock.lock(); System.out.println("sub1..." + bShould); try{ while (bShould != 0) { try { condition1.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 1; j <= 3; ++j) { System.out.println(Thread.currentThread().getName() + " sub1 Thread seq " + i + " looping " + j); } bShould = 1; condition2.signal(); }finally{ lock.unlock(); } } public void sub2(int i) { lock.lock(); System.out.println("sub2..." + bShould); try{ while (bShould != 1) { try { condition2.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 1; j <= 5; ++j) { System.out.println(Thread.currentThread().getName() + " sub2 Thread seq " + i + " looping " + j); } bShould = 2; condition3.signal(); }finally{ lock.unlock(); } } public void sub3(int i) { lock.lock(); System.out.println("sub3..." + bShould); try{ while (bShould != 2) { try { condition3.await(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 1; j <= 8; ++j) { System.out.println(Thread.currentThread().getName() + " sub2 Thread seq " + i + " looping " + j); } bShould = 0; condition1.signal(); }finally{ lock.unlock(); } } }