0
点赞
收藏
分享

微信扫一扫

java线程间通信之wait/notify实现

想一下,在没有等待/通知之前,如何实现线程间通信?

一般都是多个线程共享同一个变量,然后根据变量的变化决定相应操作。但是多线程获取共享变量值这个过程既耗时,又不能保证完全正确。

所以需要引入等待/通知机制。

方法wait()可以使当前执行代码的线程进入等待状态,wait()是object类的方法,在调用wait()前,线程必须获得该对象的对象级别锁,也就是只能在同步方法或同步方法块中执行该方法,否则会抛一个runtimeexception,IllegalMonitorStateException,运行时异常不需要try-cach。

方法notify()可以使当前对象中某个正在等待的线程变为继续执行,它和wait()方法的使用条件类似。有一点要注意,那就是在执行notify()方法后,当前线程并不会立马释放锁,而是要等到同步方法或同步代码块执行完,它才会释放锁。

 

在同步代码块中使用wait的总结:

1)同步代码块执行完,对象的锁就会自动释放。

2)同步代码块里出现异常导致线程终止,锁也会释放。

3)当线程调用wait呈等待状态时,调用此线程的interrupt方法,会报InterruptedException异常。

 

wait()还可以这样用wait(xxx).

 

当在使用wait/notify机制时,要注意不要提前notify,那样可能导致后面执行wait的线程永远不被唤醒。

实例生产者/消费者

 

最后来个示例,20个线程备份数据库,A-B-A-B。。。这样进行交叉备份,看代码

1 public class DBtools {
2
3 String flag = "A";
4
5 synchronized public void backupA(){
6 try {
7 while (flag.equals("B")) {
8 wait();
9 }
10 System.out.println("备份数据到A库");
11 Thread.sleep(1000);
12 flag = "B";
13 notifyAll();
14 } catch (InterruptedException e) {
15 e.printStackTrace();
16 }
17 }
18 synchronized public void backupB(){
19 try {
20 while (flag.equals("A")) {
21 wait();
22 }
23 System.out.println("备份数据到B库");
24 Thread.sleep(1000);
25 flag = "A";
26 notifyAll();
27 } catch (InterruptedException e) {
28 e.printStackTrace();
29 }
30 }
31 }
1 public class BackupA extends Thread {
2 private DBtools dBtools;
3 public BackupA(DBtools dBtools) {
4 this.dBtools = dBtools;
5 }
6 @Override
7 public void run() {
8 dBtools.backupA();
9 }
10 }
1 public class BackupB extends Thread {
2 private DBtools dBtools;
3 public BackupB(DBtools dBtools) {
4 this.dBtools = dBtools;
5 }
6 @Override
7 public void run() {
8 dBtools.backupB();
9 }
10 }
1 public class Run {
2 public static void main(String[] args) {
3 DBtools dBtools = new DBtools();
4 for (int i = 0; i < 10; i++) {
5 BackupA backupA = new BackupA(dBtools);
6 BackupB backupB = new BackupB(dBtools);
7 backupA.start();
8 backupB.start();
9 }
10 }
11 }

 


举报

相关推荐

多线程编程之wait、notify

0 条评论