【问题标题】:Class Level and Object Level lock synchronization类级别和对象级别锁同步
【发布时间】:2014-03-20 00:56:19
【问题描述】:
class MyClass
{
    public synchronized void print() {}

    public static synchronized void buffer() {}
}

使静态对象同步会生成一个只有一个线程可以访问的 CLASS 级对象。该类具有静态和非静态同步方法。

  1. 其他线程(线程-B)能否通过对象锁访问非静态同步方法(),而另一个线程(线程-A)使用静态同步(获取类级锁)方法?

  2. 我希望在 (Thread-B) 释放锁之前,没有线程访问任何静态同步方法。

【问题讨论】:

    标签: java multithreading static


    【解决方案1】:

    您的两个问题的答案都是“是”:静态级锁不会阻塞实例级synchronized 方法,它们适用于所有静态synchronized 方法。

    不过,通常不鼓励在类上进行同步,因为这会使您的类暴露于无限等待攻击。肇事者在类上同步,阻止你所有的静态 synchronized 方法运行。更好的方法是创建一个私有对象进行锁定,并在其上使用synchronize,如下所示:

    class MyClass
    {
        public synchronized void print() {}
    
        private static Object staticLock = new Object();
        public static void buffer() {
            synchronized(staticLock) {
                ...
            }
        }
    }
    

    同步实例方法也是如此:如果要在潜在的非合作环境中使用该类,最好使用私有对象进行锁定。

    【讨论】:

    • 如果没有不受信任的代码在同一个虚拟机中运行,这种攻击是否重要?
    • @immibis 不,如果在 VM 上运行的所有代码都是您的,您可以放心地忽略这一点。这可能很重要的唯一地方是当您构建一个用于大规模发行版的库时,或者当您将它提供给没有与您直接沟通渠道的开发人员时。
    • 谁会认为在不属于他们的随机类对象上进行同步是个好主意?
    • @immibis 想要对您的系统造成损害的人 - 例如,通过阻止在其公共类之一上同步的通信库确认来自服务器的消息,以阻止您的库在当它需要更新其关键文件之一或做同样邪恶的事情时。
    • 抱歉不清楚。我的意思是在非恶意情况下。这样做似乎是一件坏事,因为它会阻塞同步的静态方法。
    【解决方案2】:

    简而言之:

    • 非静态方法使用当前对象的锁(每个对象只有一个线程)

    • 静态方法使用关联的Class 对象(每个类有一个,所以每个Class 对象只有一个therad)

    考虑擦除很重要:

    // If you have this:
    
    class MyClass<T> {
    
        static synchronized myMethod() { ... }
    
    }
    
    MyClass<Integer> objInt = new MyClass<Integer>();
    
    MyClass<String> objString = new MyClass<String>();
    
    // Then only one thread will be able to execute myMethod(),
    // even when ojbInt and ObjString are not "exactly" the "same"
    // class in compilation time
    

    【讨论】:

      【解决方案3】:

      静态锁
      同步(YourClass.class/类对象)

      实例锁
      同步(此/实例对象)
      两者不互斥,两个线程会同时运行

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-27
        • 1970-01-01
        • 2017-10-30
        • 2023-03-04
        • 2016-02-07
        • 2018-04-17
        • 1970-01-01
        相关资源
        最近更新 更多