Fork me on GitHub

多线程-wait/notify方法

wait方法

作用

1.结合以下例子进行叙述。

lock.wait();这句执行后线程a会释放锁,线程a会进入阻塞状态,等待线程b的lock.notify()执行后,才可以尝试获取锁,a线程等待获取锁,当b线程锁住的lock对象代码块执行完并释放锁后,a线程才可以得到锁进入运行状态。

2.如下图

step
1 1557466558215
2 1557466606428
3 1557466652754
4 1557466712774
5 1557466792903

MyList.java

1
2
3
4
5
6
7
8
9
10
11
12
public class MyList {
private static List<String> list = new ArrayList<String>();

public static void add() {
list.add("anyString");
}

public static int size() {
return list.size();
}

}

ThreadA.java

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
public class ThreadA extends Thread {

private Object lock;

public ThreadA(Object lock) {
super();
this.lock = lock;
}

@Override
public void run() {
try {
synchronized (lock) {
if (MyList.size() != 5) {
System.out.println("wait begin "
+ System.currentTimeMillis());
lock.wait();
System.out.println("wait end "
+ System.currentTimeMillis());
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

ThreadB.java

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
public class ThreadB extends Thread {
private Object lock;

public ThreadB(Object lock) {
super();
this.lock = lock;
}

@Override
public void run() {
try {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
MyList.add();
if (MyList.size() == 5) {
lock.notify();
/*
发出通知后,b线程并不会释放锁,必须等待synchronized (lock){...}执行完才会释放锁,a线程才可以获得锁。
*/
System.out.println("已发出通知!");
}
System.out.println("添加了" + (i + 1) + "个元素!");
Thread.sleep(1000);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

Run.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Run {

public static void main(String[] args) {

try {
Object lock = new Object();

ThreadA a = new ThreadA(lock);
a.start();

Thread.sleep(50);//等待线程a进入阻塞状态,释放锁。

ThreadB b = new ThreadB(lock);
b.start();
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}

运行结果: