synchronized(Foo.Class){
//some code..
}
这会锁定Foo类的所有实例还是仅锁定静态方法/字段?
答案 0 :(得分:6)
它进入Foo.class
对象的监视器。如果另一个方法同步Foo.Class
,则必须等待,假设它在不同的线程中。
如果方法没有同步,那么它将不受影响,无论它是否是静态的。并非同步的静态方法在定义它们的类的类对象上隐式同步。
答案 1 :(得分:1)
类对象的同步与实例的同步完全一样。像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中是大括号的结尾 }
)。
答案 2 :(得分:0)
它同步对使用它的方法/ synchronized子句的访问。这些可能是Bar类的方法 - 不一定是Foo。
重要的是,所有在“Foo.class”上同步的方法/ synchronized子句都会被同时执行。
同步根本不会影响字段 - 无法声明字段已同步。
答案 3 :(得分:-1)
我对tutorial 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
当任务2更新valueB
而任务1持有实例锁时,我认为这表明静态锁不会锁定该类的所有实例。