传统线程间通信
// 传统的线程通信 public class TraditionalThreadCommunication { 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.sub(i); } } }).start(); // 注意:若将主线程代码放到子线程前执行,程序将死锁, // 因主线程一直等待,而子线程又无法去执行改变变量值. for (int i = 1; i <= 50; i++) { business.main(i); } } } class Business { // 让子线程先运行 private boolean bShouldSub = true; public synchronized void sub(int i) { System.out.println("sub()..."); while (!bShouldSub) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 1; j <= 10; j++) { System.out.println("sub thread sequence of " + j + ",loop of " + i); } bShouldSub = false; this.notify(); } public synchronized void main(int i) { System.out.println("main()..."); while (bShouldSub) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int j = 1; j <= 100; j++) { System.out.println("main thread sequence of " + j + ",loop of " + i); } bShouldSub = true; this.notify(); } }
基于Lock与Condition的线程通信
Condition的功能类似在传统线程中的wait()和notify()的功能,在等待Condition时,允许发生"虚假唤醒",这通常作为对基础平台语义的让步,对于大多数应用程序,这带来的影响很小,因Condition应总是在一个循环中被等等,并测试正被等待的状态声明,某个实现可以随意移除可能的虚假唤醒,但建议应用程序中虚假唤醒可能发生,因此总是在一个循环中等待.
public class ConditionCommunication { 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.sub(i); } } }).start(); for (int i = 1; i <= 50; i++) { business.main(i); } } static class Business { // 可重入锁 Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); // 让子线程先运行 private boolean bShouldSub = true; public void sub(int i) { lock.lock(); System.out.println("sub lock status:" + ((ReentrantLock)lock).isLocked()); try { while (!bShouldSub) { try { condition.await(); } catch (Exception e) { e.printStackTrace(); } } for (int j = 1; j <= 10; j++) { System.out.println("sub thread sequence of " + j + ",loop of " + i); } bShouldSub = false; condition.signal(); } finally { lock.unlock(); } } public void main(int i) { lock.lock(); System.out.println("main lock status:" + ((ReentrantLock)lock).isLocked()); try { while (bShouldSub) { try { condition.await(); } catch (Exception e) { e.printStackTrace(); } } for (int j = 1; j <= 100; j++) { System.out.println("main thread sequence of " + j + ",loop of " + i); } bShouldSub = true; condition.signal(); } finally { lock.unlock(); } } } }