class 的 synchronized(this) 和 few synchronized 方法的区别
Difference between synchronized(this) and few synchronized methods of class
在 Programming Interviews Exposed 书(Wrox 出版物)中,生产者消费者问题的代码对名为 IntBuffer 的 class 中的每个 produce() 和 consume() 方法使用了 'synchronized' 关键字。这与在每个方法中使用 synchronized(this) 不同吗?书上说,"When a thread is busy waiting in produce(), no thread can enter consume() because methods are synchronized."我觉得书上的代码没有意义,因为当一个线程忙于等待produce()时,没有线程可以进入produce()。然而其他线程可以进入 consume() 这打破了互斥的想法。 produce 和 consume 方法应该完全同步,对吗?
书中代码:
public class IntBuffer
{
private int index;
private int[] buffer = new int[8];
// Function called by producer thread
public synchronized void produce(int num) {
while(index == buffer.length - 1) {
try { wait();}
catch(InterruptedException ex) {}
}
buffer[index++] = num;
notifyAll();
}
// Function called by consumer thread
public synchronized int consume() {
while(index == 0) {
try { wait();}
catch(InterruptedException ex) {}
}
int ret = buffer[--index];
notifyAll();
return ret;
}
}
问:这与在每个方法中使用 synchronized(this) 有什么不同吗?
A : 不,没有什么不同,通过使用 block (synchronize(this) 你可以只同步部分代码,而不是整个方法。
例如:
public void m1(){
// some code
synchronized(this){
// thread-safe code
}
Is this different than using synchronized(this) inside each of those methods?
没有
The book says, "When a thread is busy waiting in produce(), no thread can enter consume() because methods are synchronized." I don't feel that makes sense for the code in the book because, when a thread is busy waiting in produce(), no thread can enter produce(). However other thread can enter consume() which shatters the idea of mutual exclusion.
这是不正确的。两种方法都在同一对象上同步,因此任一方法中只能有一个线程,除非调用 wait()
,它会释放锁。
The methods produce and consume should both entirely be synchronized right?
是的,你说他们是。不清楚你在这里问什么。
不,它们是一样的。
private synchronized void foo() {}
private void foo2() {
synchronized(this){
}
}
它们将执行完全相同的操作,因为它们都监视调用它们的实例。
可以在 Jakob Jenkov 的博客中找到很好的教程
http://tutorials.jenkov.com/java-concurrency/synchronized.html#java-synchronized-example
编码愉快!
使用 synchronized(this) 要求调用线程获取与在方法上使用 synchronized 修饰符调用实例方法时相同的锁。生成的字节码存在一些差异,但这是一个非常低级的区别。
synchronized 关键字的目的是保护共享状态不被并发访问。 produce 和 consume 方法使用相同的内部状态,因此它们都受到相同锁的保护是合理的。
发布的代码看起来做得很好,我唯一的挑剔是我会让方法抛出 InterruptedException 而不是捕获它。 produce 和 consume 方法都需要调用线程获取调用该方法的实例上的锁。
在 Programming Interviews Exposed 书(Wrox 出版物)中,生产者消费者问题的代码对名为 IntBuffer 的 class 中的每个 produce() 和 consume() 方法使用了 'synchronized' 关键字。这与在每个方法中使用 synchronized(this) 不同吗?书上说,"When a thread is busy waiting in produce(), no thread can enter consume() because methods are synchronized."我觉得书上的代码没有意义,因为当一个线程忙于等待produce()时,没有线程可以进入produce()。然而其他线程可以进入 consume() 这打破了互斥的想法。 produce 和 consume 方法应该完全同步,对吗?
书中代码:
public class IntBuffer
{
private int index;
private int[] buffer = new int[8];
// Function called by producer thread
public synchronized void produce(int num) {
while(index == buffer.length - 1) {
try { wait();}
catch(InterruptedException ex) {}
}
buffer[index++] = num;
notifyAll();
}
// Function called by consumer thread
public synchronized int consume() {
while(index == 0) {
try { wait();}
catch(InterruptedException ex) {}
}
int ret = buffer[--index];
notifyAll();
return ret;
}
}
问:这与在每个方法中使用 synchronized(this) 有什么不同吗? A : 不,没有什么不同,通过使用 block (synchronize(this) 你可以只同步部分代码,而不是整个方法。 例如:
public void m1(){
// some code
synchronized(this){
// thread-safe code
}
Is this different than using synchronized(this) inside each of those methods?
没有
The book says, "When a thread is busy waiting in produce(), no thread can enter consume() because methods are synchronized." I don't feel that makes sense for the code in the book because, when a thread is busy waiting in produce(), no thread can enter produce(). However other thread can enter consume() which shatters the idea of mutual exclusion.
这是不正确的。两种方法都在同一对象上同步,因此任一方法中只能有一个线程,除非调用 wait()
,它会释放锁。
The methods produce and consume should both entirely be synchronized right?
是的,你说他们是。不清楚你在这里问什么。
不,它们是一样的。
private synchronized void foo() {}
private void foo2() {
synchronized(this){
}
}
它们将执行完全相同的操作,因为它们都监视调用它们的实例。
可以在 Jakob Jenkov 的博客中找到很好的教程 http://tutorials.jenkov.com/java-concurrency/synchronized.html#java-synchronized-example
编码愉快!
使用 synchronized(this) 要求调用线程获取与在方法上使用 synchronized 修饰符调用实例方法时相同的锁。生成的字节码存在一些差异,但这是一个非常低级的区别。
synchronized 关键字的目的是保护共享状态不被并发访问。 produce 和 consume 方法使用相同的内部状态,因此它们都受到相同锁的保护是合理的。
发布的代码看起来做得很好,我唯一的挑剔是我会让方法抛出 InterruptedException 而不是捕获它。 produce 和 consume 方法都需要调用线程获取调用该方法的实例上的锁。