synchronized(Foo.Class){
//some code..
}
这是否会锁定Foo类的所有实例,还是只锁定其静态方法/字段?
synchronized(Foo.Class){
//some code..
}
Foo.class
对象。如果另一个方法也在Foo.Class
上同步,它将不得不等待,假设它在另一个线程中。Foo.class
这样的类就是一个对象,因此具有内置监视器。您提供的代码:synchronized(Foo.Class){
//some code..
}
同步访问Foo类。当尝试同步一个类的静态变量时,它非常有用。例如:
public class Foo{
private static int COUNTER = 0;
synchronized public static void increment(){
COUNTER ++;
}
public static void decrement(){
synchronized (Foo.class) {
COUNTER ++;
}
}
}
Foo.class
的同步可以与任何实例相同地实现。当尝试同步实例的代码块时,使用synchronized(this){}
,它等价于在类对象的情况下:synchronized(Foo.class){}
。对于同步方法也是同样的道理:synchronized public void increment(){}
等同于:synchronized public static void increment(){}
现在关于您的问题:
当然,它不会获取所有实例的锁,如上所述。此外,类对象不知道创建的实例。是否锁定了 Foo 类的所有实例还是仅其静态方法/字段?
synchronized
块不锁定字段,它只锁定一段代码/方法,该代码/方法由获取该锁的线程强制执行为原子操作,直到第一个线程释放该锁(在 Java 中是右括号}
的结尾)。它同步对使用它的方法/同步子句的访问。这些可以是类Bar的方法 - 不一定是Foo。
重要的是,所有在"Foo.class"上同步的方法/同步子句都被互斥地排除在同时执行之外。
同步不会对字段产生任何影响 - 没有办法声明一个同步字段。
我对 教程 中 synchronized(Foo.class) {...}
的理解是只锁定类的静态成员。但为了确保,您需要编写一个测试。
public class SyncTest {
public static SyncTest instance;
public static String valueA;
public String valueB;
public static void main(String[] args) {
instance = new SyncTest();
(new Thread(new Task1())).start();
(new Thread(new Task2())).start();
try {
Thread.sleep(10000);
synchronized(SyncTest.class) {
System.out.println("Value A: " + valueA);
}
synchronized(instance) {
System.out.println("Value B: " + instance.valueB);
}
} catch (InterruptedException interrupt) { }
}
}
class Task1 implements Runnable {
public void run() {
try {
synchronized(SyncTest.class) {
System.out.println("Task 1 Sleeping ");
Thread.sleep(500);
SyncTest.valueA = "One";
System.out.println("T1 A: " + SyncTest.valueA);
}
synchronized(SyncTest.instance) {
Thread.sleep(1000);
SyncTest.instance.valueB = "Two";
System.out.println("T1 B: " + SyncTest.instance.valueB);
}
} catch (InterruptedException interrupt) { }
System.out.println("Task 1 Finished ");
}
}
class Task2 implements Runnable {
public void run() {
System.out.println("Task 2 Started");
try {
Thread.sleep(1000);
synchronized(SyncTest.class) {
SyncTest.instance.valueB = "Four";
System.out.println("T2 B: " + SyncTest.instance.valueB);
Thread.sleep(5000);
SyncTest.valueA = "Three";
System.out.println("T2 A: " + SyncTest.valueA);
}
} catch (InterruptedException interrupt) { }
System.out.println("Task 2 Finished");
}
}
这将输出:
Task 1 Sleeping
Task 2 Started
T1 A: One
T2 B: Four
T1 B: Two
Task 1 Finished
T2 A: Three
Task 2 Finished
Value A: Three
Value B: Two
在任务1持有实例锁的同时,任务2更新valueB
,我认为这表明静态锁并不能锁定类的所有实例。