关于并发的问题
Questions about concurrency
如果我理解正确的话,synchronized 应该足以确保一次只有一个线程可以访问资源:
当一个线程想要执行一个同步块时,它获取监视器并在同步块结束时自动释放它,与此同时,所有其他试图访问已被监视器占用的同步块的线程是放入队列,只要程序是 运行.
,就会继续尝试访问同步方法
如果我在同步块内调用 wait(),那么我最终可能会在同步块内有多个线程,而且我还被迫在块末尾调用 notify() 以避免线程永远等待。
- 首先,我刚才说的对吗?如果不是,怎么了?
- 如果是,synchronized 应该与 wait() 和 notify() 一起使用的最常见情况是什么?
- 一般来说,如果我通过向 synchronized 添加 wait() 和 notify() 来使代码更复杂,那么使用像 ReentrantLocks 这样更复杂的工具会更好吗?
First of all, is what I just stated correct? If it is not, what's wrong?
前两段是正确的。关于等待/通知的第三段大部分是正确的。不过有几点:
- 一些线程需要调用
notify
或notifyAll
。但不一定非得是这一个。
- 您可以随时调用,而不仅仅是在块的末尾。无论哪种方式,通知都不会发生,直到当前线程离开块。
- 等待从未到达的通知的线程不一定永远卡住。例如,线程中断将导致
wait
以 InterruptedException
. 终止
If it is, what are the most commons situations where synchronized
should be used with wait()
and notify()
?
“应该”这个词是一个有内涵的词。您 可以 使用 wait()
和 notify()
的情况是一个线程需要等待某个事件发生的情况。 (通常这用于实现条件变量。)但根据具体情况,可能有更好的方法。
此外,如果没有 持有关联的互斥体,则不能使用wait()
和notify()
。 (如果你尝试这样做,你会得到一个例外!)
In general, if I'm making the code more complex by adding wait()
and notify()
to synchronized
, would it be better to just use a more sophisticated tool like ReentrantLocks
?
一般不会。
如果有更高级别的并发 classes 可以做你想做的事情,通常最好使用它们而不是原始互斥锁 + 等待/通知。但情况并非总是如此。
您提到了 ReentrantLock
。这个 class 实际上只是“在类固醇上”的类似互斥锁的锁。它们有一些原始互斥锁不可用的特性(比如 tryLock
和查看哪些线程正在等待),但是如果你不需要 需要 额外的特性就没有了使用 ReentrantLock
优于原始互斥体的真正优势。 (一个可能的 缺点 是 Lock
classes 不会在块退出时自动释放。所以你真的需要将它们与 try ... finally
或 try
与资源。)
如果我理解正确的话,synchronized 应该足以确保一次只有一个线程可以访问资源:
当一个线程想要执行一个同步块时,它获取监视器并在同步块结束时自动释放它,与此同时,所有其他试图访问已被监视器占用的同步块的线程是放入队列,只要程序是 运行.
,就会继续尝试访问同步方法如果我在同步块内调用 wait(),那么我最终可能会在同步块内有多个线程,而且我还被迫在块末尾调用 notify() 以避免线程永远等待。
- 首先,我刚才说的对吗?如果不是,怎么了?
- 如果是,synchronized 应该与 wait() 和 notify() 一起使用的最常见情况是什么?
- 一般来说,如果我通过向 synchronized 添加 wait() 和 notify() 来使代码更复杂,那么使用像 ReentrantLocks 这样更复杂的工具会更好吗?
First of all, is what I just stated correct? If it is not, what's wrong?
前两段是正确的。关于等待/通知的第三段大部分是正确的。不过有几点:
- 一些线程需要调用
notify
或notifyAll
。但不一定非得是这一个。 - 您可以随时调用,而不仅仅是在块的末尾。无论哪种方式,通知都不会发生,直到当前线程离开块。
- 等待从未到达的通知的线程不一定永远卡住。例如,线程中断将导致
wait
以InterruptedException
. 终止
If it is, what are the most commons situations where
synchronized
should be used withwait()
andnotify()
?
“应该”这个词是一个有内涵的词。您 可以 使用 wait()
和 notify()
的情况是一个线程需要等待某个事件发生的情况。 (通常这用于实现条件变量。)但根据具体情况,可能有更好的方法。
此外,如果没有 持有关联的互斥体,则不能使用wait()
和notify()
。 (如果你尝试这样做,你会得到一个例外!)
In general, if I'm making the code more complex by adding
wait()
andnotify()
tosynchronized
, would it be better to just use a more sophisticated tool likeReentrantLocks
?
一般不会。
如果有更高级别的并发 classes 可以做你想做的事情,通常最好使用它们而不是原始互斥锁 + 等待/通知。但情况并非总是如此。
您提到了 ReentrantLock
。这个 class 实际上只是“在类固醇上”的类似互斥锁的锁。它们有一些原始互斥锁不可用的特性(比如 tryLock
和查看哪些线程正在等待),但是如果你不需要 需要 额外的特性就没有了使用 ReentrantLock
优于原始互斥体的真正优势。 (一个可能的 缺点 是 Lock
classes 不会在块退出时自动释放。所以你真的需要将它们与 try ... finally
或 try
与资源。)