前言:java Object的wait与notify方法
线程间通信的方式主要为共享内存、线程同步。
线程同步除了synchronized互斥同步外,也可以使用wait/notify实现等待、通知的机制。
(1)wait/notify属于Object类的方法,但wait和notify方法调用,必须获取对象的对象级别锁,即synchronized同步方法或同步块中使用。
(2)wait()方法:在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,或者其他某个线程中断当前线程,导致当前线程一直阻塞等待。等同wait(0)方法。
wait(long timeout) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。 单位为毫秒。
void wait(long timeout, int nanos) 与 wait(long timeout) 不同的是增加了额外的纳秒级别,更精细的等待时间控制。
(3)notfiy方法:唤醒在此对象监视器上等待的单个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个wait方法,在对象的监视器上等待。
(4)notifyAll方法:唤醒在此对象监视器上等待的所有线程。
需要:wait被执行后,会自动释放锁,而notify被执行后,锁没有立刻释放,由synchronized同步块结束时释放。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| import java.util.Random;
public class Main { private static boolean mutex = true; private static int resources = 0; Random random = new Random(); class MyThreadSub implements Runnable{ public void run() { for (int i = 1; i <= 20; i++) { sub(); } } } class MyThreadAdd implements Runnable{ public void run() { for (int i = 1; i <= 20; i++) { add(); } } } synchronized void sub() { while (!mutex||resources<0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int i=0;i<random.nextInt(10)&&resources>0;i++) { resources--; System.out.println("sub thread execute,resources: " + resources); } mutex = false; this.notify(); } synchronized void add() { while (mutex) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int i=0;i<random.nextInt(10);i++){ resources++; System.out.println("add thread execute,resources: "+resources); }
mutex = true; this.notify(); } public static void main(String[] args) { Main main = new Main(); Thread threadAdd = new Thread(main.new MyThreadAdd()); Thread threadSub = new Thread(main.new MyThreadSub()); threadAdd.start(); threadSub.start(); } }
|