为什么我们需要在等待和通知时使用互斥锁?

15 浏览
0 Comments

为什么我们需要在等待和通知时使用互斥锁?

我开始更深入地研究多线程,并且不太确定为什么在使用等待/通知机制时需要添加 synchronized 关键字。请问有人可以解释一下吗?

0
0 Comments

为了解释为什么在使用wait和notify方法时需要互斥锁(mutex),我们先来看一个示例。假设有一个线程从缓冲区中读取数据,另一个线程将数据写入缓冲区。读取数据的线程需要等待,直到写入数据的线程完全将一块数据写入缓冲区。写入数据的线程需要等待,直到读取数据的线程完全从缓冲区中读取数据。如果wait()和notify()方法可以被普通方法调用,那么读取线程调用wait()后会被添加到等待队列中。就在这个时刻,写入线程调用notify()来通知条件发生了变化。但是读取线程错过了这个变化并一直等待下去。因此,由于这里存在竞态条件,我们潜在地丢失了一个通知。如果我们使用缓冲区或只有一个线程,那么程序将永远等待下去,导致程序挂起。

由于Java中的wait()方法在等待之前会释放锁,并在从wait()方法返回之前重新获取锁,我们必须使用互斥锁来确保检查条件(缓冲区是否已满)和设置条件(从缓冲区中取出元素)是原子操作。这可以通过在Java中使用同步方法或块来实现。因此,它们必须在同步方法或块中调用,这是互斥的。

等待队列是指在调用wait()方法后,线程被添加到等待队列中,以等待条件满足并被唤醒。如果多个线程在同一个对象上调用wait()方法,它们将按照调用wait()方法的顺序被添加到等待队列中。

以上内容解释了为什么在使用wait和notify方法时需要互斥锁的原因。这篇文章的内容来源于xyzws.com/javafaq/…

0