目录

Wait() 与 Notify()

Wait()Notify()常出现在多线程编程中,当线程想保留资源且希望线程能够随时重获资源时,就需要使用这两个函数。

class TaskQueue {
    Queue<String> queue = new LinkedList<>();

    public synchronized void addTask(String s) {
        this.queue.add(s);
    }

    public synchronized String getTask() {
        while (queue.isEmpty()) {
        }
        return queue.remove();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

上面这段代码中,当我们调用addTask()时,能为队列添加元素,由于该方法声明了synchronized,因此会将资源上锁。而当我们调用getTask()时,会检测队列是否为空,如果为空就陷入while循环,否则获取元素。

我们希望该组函数实现的功能是:

  1. 如果队列不为空,则返回元素
  2. 如果队列为空,则陷入while循环等待其他线程调用addTask(),然后再返回新的元素出去。

但事实并不如我们所料,当队列为空时,getTask()会卡在while循环,无法释放锁。这意味着其他人也无法调用addTask()去添加元素。

那么有没有一种方法能让getTask()暂时释放锁,等添加元素后再重新获取锁呢?

那就需要依靠Wait()Notify()了。

class TaskQueue {
    Queue<String> queue = new LinkedList<>();

    public synchronized void addTask(String s) {
        this.queue.add(s);
		this.notify(); //唤醒wait();
    }

    public synchronized String getTask() {
        while (queue.isEmpty()) {
			this.wait(); // 暂时释放锁
        }
        return queue.remove();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

我们为addTask()getTask()分别调用了Wait()Notify(),这样,当队列为空时,会暂时放弃锁,等其他人调用addTask()时,会唤醒他,并继续任务。

# 注意

Notify()是随机唤醒一个wait(),这里更加推荐使用notifyAll(),该方法能够唤醒所有wait(),这函数更加安全,避免了[[线程饥饿]]

最近更新
01
基本知识
07-18
02
卷积神经网络识别图像
07-18
03
损失函数
07-18
更多文章>