0%

wait与notify

前言: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();
}
}
-------------本文结束感谢您的阅读-------------