当我尝试遵循时
public class Test {
synchronized(this){ // compiler complains here
System.out.println("instance block");
}
public static void main(String [] args){
}
}
同步实例块不是和同步语句块一样吗?
谢谢,巴拉特
虽然您可以在实例初始化程序块或构造函数中synchronized(this)
,但它总是毫无意义的,因为在此阶段不会共享对象。即它只能由一个线程访问。
在构造函数期间,可以使一个对象对多个线程可用,但这通常被认为是一种糟糕的做法。
为什么不在内部同步:
public class Test {
{
synchronized(this) {
System.out.println("instance block");
}
}
public static void main(String [] args){
}
}
同步实例块不是和同步语句块一样吗?
AFAIK,不,因为它不仅仅是一个"语句块",而是一个实例初始化器。如果希望同步块执行,则可以始终在初始化器内的this
引用上同步。此外,我不认为您可以在顶级块上同步(方法块对此有特殊的语法支持,正如您所知)。
public class Test {
// can't synchronize on a top-level block
synchronized(this) {
}
{
// OK
synchronized(this) {
}
}
// Methods have special syntactic support
public synchronized void doIt() {
}
public void doIt() {
// same as above
synchronized(this) {
}
}
}
您实际上触及了语言推理的一部分。据说构造函数(初始化器块所属)不需要同步,因为总是从单个线程调用。另一个调用只会创建另一个实例。
但是,由于构造函数实际上可以将资源泄漏到其他实例,因此允许使用内部同步块来实现正确的同步。
因为在静态初始化程序块中没有这个。
该块在加载类定义时执行,而不是在创建实例时执行。
没有必要在静态init块内同步,因为在获得控制之前,加载类是由jvm处理的。
简而言之,保持块和删除同步(此)