【问题标题】:What does synchronized(class reference) do?同步(类引用)有什么作用?
【发布时间】:2013-03-21 17:45:43
【问题描述】:
synchronized(Foo.Class){
   //some code..
}

这是锁定 Foo 类的所有实例还是仅锁定静态方法/字段?

【问题讨论】:

  • @Chandana - 不正确。

标签: java concurrency static synchronized


【解决方案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】:

    我对@9​​87654321@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 持有实例锁时,我认为这表明静态锁不会锁定类的所有实例。

    【讨论】:

    • 它不会锁定任何东西的任何成员。它根本不锁定任何东西。它在类对象上同步
    【解决方案3】:

    它同步对使用它的方法/同步子句的访问。这些可以是 Bar 类的方法——不一定是 Foo。

    重要的是,所有在“Foo.class”上同步的方法/同步子句都相互排除在同时执行之外。

    同步根本不影响字段——没有办法声明字段同步。

    【讨论】:

      【解决方案4】:

      它进入Foo.class 对象的监视器。如果另一个方法也在 Foo.Class 上同步,它必须等待,假设它在不同的线程中。

      如果一个方法没有对其进行同步,那么无论它是否是静态的,它都不会受到影响。并不是说同步的静态方法隐式地在定义它们的类的类对象上同步。

      【讨论】:

        猜你喜欢
        • 2019-11-03
        • 2012-08-19
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        相关资源
        最近更新 更多