Java线程-同步代码
为什么必须指定哪个对象锁定了同步的代码块 您不必指定哪个对象锁定了同步方法,因为它总是被“this”(我相信)锁定 我有两个问题:Java线程-同步代码,java,multithreading,Java,Multithreading,为什么必须指定哪个对象锁定了同步的代码块 您不必指定哪个对象锁定了同步方法,因为它总是被“this”(我相信)锁定 我有两个问题: 为什么不能用对象以外的对象阻止非静态方法 “这个”? 为什么必须指定已阻止的对象 同步代码? 我已经阅读了Java6的SCJP的第九章,但我仍然不清楚这一点 我意识到这可能是一个基本的问题,但我对线程是新手 您可以锁定对象的任何实例,但程序员通常 使用此或储物柜 因为它限制了其他线程对该部分代码的访问 (代码处理单元)所以你要确保整个部分都在 一致性和其他线程不
- 为什么不能用对象以外的对象阻止非静态方法 “这个”?
- 为什么必须指定已阻止的对象 同步代码?
此
或储物柜
a = 1;
a++;
一个线程到达第二行,您希望a=2
,但另一个线程执行第一行,而不是2,第一个线程的a=1
,第二个线程的a=2
。现在:
synchronized (whatever)
{
a = 1;
a++;
}
现在,第二个线程将被阻止进入代码块
(synchronized
主体),直到第一个线程离开它(释放锁)
此
或储物柜
a = 1;
a++;
一个线程到达第二行,您希望a=2
,但另一个线程执行第一行,而不是2,第一个线程的a=1
,第二个线程的a=2
。现在:
synchronized (whatever)
{
a = 1;
a++;
}
现在,第二个线程将被阻止进入
代码块(synchronized
主体),直到第一个线程离开它(释放锁)。您可以指定需要的任何对象,该对象应在同步代码块上具有锁。实际上,您根本不应该使用synchronize(this)
(或者可能要小心,请参见)。您可以指定要锁定同步代码块的任何对象。实际上,您根本不应该使用同步(this)
(或者可能要小心,请参阅)
为什么不能用“this”以外的对象阻止非静态方法
你可以:
public void foo() {
synchronized (lock) {
...
}
}
为什么必须指定阻止同步代码的对象
因为这就是语言设计者选择设计语言的方式synchronized
在实例方法上使用时,隐式使用此
作为锁<代码>同步
在块上使用时必须明确指定锁
为什么不能用“this”以外的对象阻止非静态方法
你可以:
public void foo() {
synchronized (lock) {
...
}
}
为什么必须指定阻止同步代码的对象
因为这就是语言设计者选择设计语言的方式synchronized
在实例方法上使用时,隐式使用此
作为锁<代码>同步
在块上使用时必须明确指定锁。您可以。
代码
synchronized foo() {
// some stuff
}
逻辑上等于代码
foo() {
synchronized(this) {
// some stuff
}
}
我之所以说“逻辑上”,是因为这两个示例生成不同的字节码
如果方法foo()
是静态的,则完成类对象的同步
但是,您可能希望创建多个同步块,这些块在不同对象上同步到一个类中,甚至同步到一个方法中。在这种情况下,您可以使用synchronized(lock)
,其中lock
不是this
:
foo() {
synchronized(one) {}
///..........
synchronized(two) {}
}
你可以。
代码
synchronized foo() {
// some stuff
}
逻辑上等于代码
foo() {
synchronized(this) {
// some stuff
}
}
我之所以说“逻辑上”,是因为这两个示例生成不同的字节码
如果方法foo()
是静态的,则完成类对象的同步
但是,您可能希望创建多个同步块,这些块在不同对象上同步到一个类中,甚至同步到一个方法中。在这种情况下,您可以使用synchronized(lock)
,其中lock
不是this
:
foo() {
synchronized(one) {}
///..........
synchronized(two) {}
}
每个对象都有一个可以同步的锁: 最终对象锁=新对象() 已同步(锁定){…} 如果你想同步整个方法,你不能说是哪个对象,所以它总是“this”对象 同步的foo(){…}
顺便说一下,第一种锁定方式更好。每个对象都有一个可以同步的锁定: 最终对象锁=新对象() 已同步(锁定){…} 如果你想同步整个方法,你不能说是哪个对象,所以它总是“this”对象 同步的foo(){…}
顺便说一句,第一种锁定方式更好。不建议使用此锁定每个方法,因为它在大多数情况下会降低并发性。因此,建议使用锁剥离,其中只有需要保护的特定代码部分保留在同步块中 这是一种在实践中得到很好解释的做法。但请注意,这本书只有在您有一些线程的基本经验时才有用 要记住一些金块:
- 不要过度使用同步
- 仅当需要保护整个方法时才使用方法级同步
- 使用不同的锁来保护两个不相关的实体,这将增加并发的机会。否则,对于读取或写入两个不相关的实体,线程将阻塞在同一个锁上
public void incrementCounter1(){ synchronized(lockForCounter1){ counter1++; } } public void incrementCounter2(){ synchronized(lockForCounter2){ counter2++; } }
此
锁定每个方法,因为它会减少