多线程--两个线程间的通讯
CPU任意切换线程,如果希望 CPU能够有规律的执行,就需要线程间通讯:
this.wait() 当前线程等待
this.notify() 随机唤醒单个线程
this.notifyAll() 唤醒所有线程
// 为什么定义在object中,因为任意对象都可以成为锁
public class demon1_notify { //等待唤醒机制 public static void main(String[] args) { final printer2 p = new printer2(); new Thread(){ public void run() { while(true){ try { p.print1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ public void run() { while(true){ try { p.print2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class printer2{ private int flag = 1; public synchronized void print1() throws InterruptedException{ if (flag !=1) { this.wait(); } System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); flag = 2; this.notify(); } public synchronized void print2() throws InterruptedException{ if (flag !=2) { this.wait(); } System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); flag = 1; this.notify(); } }
public class demon2_notify2 { public static void main(String[] args) { final printer3 p = new printer3(); new Thread(){ public void run() { while(true){ try { p.print1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ public void run() { while(true){ try { p.print2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ public void run() { while(true){ try { p.print3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class printer3{ private int flag = 1; public synchronized void print1() throws InterruptedException{ while (flag !=1) { this.wait(); } System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); flag = 2; //this.notify(); this.notifyAll(); } public synchronized void print2() throws InterruptedException{ while (flag !=2) { this.wait(); } System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); flag = 3; this.notifyAll(); } public synchronized void print3() throws InterruptedException{ while (flag !=3) { this.wait(); } System.out.print("i"); System.out.print("t"); System.out.print("h"); System.out.print("m"); System.out.print("\r\n"); flag = 1; this.notifyAll(); } }
JDK5之前无法唤醒指定的一个线程,1.5.之后 有互斥锁 ,
同步
* 使用ReentrantLock类的lock()和unlock()方法进行同步
通信
* 使用ReentrantLock类的newCondition()方法可以获取Condition对象
* 需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法
* 不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import javax.print.attribute.standard.Sides; public class demon3_ReentrantLock { public static void main(String[] args) { final printer4 p4 = new printer4(); new Thread(){ public void run() { while(true){ try { p4.print1(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ public void run() { while(true){ try { p4.print2(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread(){ public void run() { while(true){ try { p4.print3(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } class printer4{ private ReentrantLock r = new ReentrantLock(); // 获取锁 private Condition c1 = r.newCondition(); private Condition c2 = r.newCondition(); private Condition c3 = r.newCondition(); private int flag = 1; public void print1() throws InterruptedException{ r.lock(); //唤醒锁 if (flag !=1) { c1.await(); } System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); flag = 2; c2.signal(); // 唤醒C2 r.unlock(); // 释放锁 } public void print2() throws InterruptedException{ r.lock(); if (flag !=2) { c2.await(); } System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); flag = 3; c3.signal(); r.unlock(); } public void print3() throws InterruptedException{ r.lock(); if (flag !=3) { c3.await(); } System.out.print("i"); System.out.print("t"); System.out.print("h"); System.out.print("m"); System.out.print("\r\n"); flag = 1; c1.signal(); r.unlock(); } }
竹杖芒鞋轻胜马,一蓑烟雨任平生。
回首向来萧瑟处,也无风雨也无晴。