sot*_*otn 12 java static synchronization
这是我在此链接中找到的一段文字.
"避免锁定静态方法
最糟糕的解决方案是将"synchronized"关键字放在静态方法上,这意味着它将锁定此类的所有实例."
为什么同步静态方法会锁定类的所有实例?它不应该只是锁定类吗?
spi*_*ker 33
要理解这一点,最简单的方法是比较锁对实例方法和静态方法的工作原理.假设您有类Test.java,它有两个方法如下.
public class Test{
public synchronized void instanceMethod(){
}
public synchronized static void staticMethod(){
}
}
Run Code Online (Sandbox Code Playgroud)
同时,有两个类Test,testA和testB.并且还有两个线程tA和tB尝试并行访问类Test.
在instanceMethod上锁定:当tA获得testA的instanceMethod上的锁时,tB无法访问testA中的相同方法,但是tB仍然可以在testB中自由调用instanceMethod.因为针对instanceMethod的同步是实例级锁定
lock on staticMethod:但是,当tA获取staticMethod上的锁时,锁与testA或testB无关,因为静态方法上的同步是类级锁定.这意味着在释放锁之前,tB根本无法访问staticMethod
实际上对类的静态方法的Foo锁定与锁定Foo.class(这是唯一的实例)相同:
public static void doSomething()
{
synchronized(Foo.class)
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试代码,表明你是对的,文章有点过于谨慎:
class Y {
static synchronized void staticSleep() {
System.out.println("Start static sleep");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("End static sleep");
}
synchronized void instanceSleep() {
System.out.println("Start instance sleep");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
System.out.println("End instance sleep");
}
}
public class X {
public static void main(String[] args) {
for (int i = 0; i < 2; ++i) {
new Thread(new Runnable() {
public void run() {
Y.staticSleep();
}
}).start();
}
for (int i = 0; i < 10; ++i) {
new Thread(new Runnable() {
public void run() {
new Y().instanceSleep();
}
}).start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
打印:
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start static sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
Start instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End instance sleep
End static sleep
Start static sleep
End static sleep
Run Code Online (Sandbox Code Playgroud)
所以这与实例static synchronized上的synchronized方法没有关系......
当然,如果static synchronised在整个系统中使用方法,那么你可以期望它们对多线程系统的吞吐量产生最大的影响,所以在你的危险中使用它们......