【问题标题】:About java critical section and lock, lock on object/data or lock on code?关于java临界区和锁,锁定对象/数据还是锁定代码?
【发布时间】:2014-04-06 09:31:20
【问题描述】:
 synchronized(foo){
   //code
 }

假设另一个线程使用另一个代码块来访问这个 foo 对象。那么会发生什么?

如果锁在 foo 对象上,那么即使不在这个临界区的代码也不能访问 foo 对象。

如果锁在这个代码块上,那么只有两个线程不能同时运行这个代码块。但是 foo 对象仍然可以通过使用另一个代码块来访问。

锁定对象或锁定代码,什么是真的?

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    在对象上同步不会阻止任何线程访问该对象。它可以防止其他线程执行在同一对象上也同步的任何代码块。

    如果你有

    public class Foo {
    }
    
    public class SharedState
        private final Foo foo = new Foo();
    
        private long value;
    
        public void increment() {
            synchronized (foo) {
                value++;
            }
        }
    
        public long getValue() {
            synchronized (foo) {
                return value;
            }
        }
    }
    

    那么如果一个线程当前正在递增或获取该值,则没有其他线程无法同时递增或读取该值。

    如果你添加一个方法

    public Foo getFoo() {
        return foo;
    }
    

    SharedState,任何线程都可以调用它,并且可以同时调用foo的任何方法。

    【讨论】:

      【解决方案2】:

      语句synchronized(foo) 同步于foo 引用的对象

      它不锁定foo,但它锁定了foo监视器。访问对象foo 的其他线程可以毫无问题地这样做,如果它们不同步的话。

      但是在synchronized 块内一次只能有一个线程在指向foo 的对象上同步。

      因此,您必须小心,只有在受到foo 监视器上的锁保护时才能访问可能发生竞争条件的变量。

      (但是即使同步了还是会出现很多问题)

      【讨论】:

        【解决方案3】:

        这是对象监视器上的锁。它防止另一个线程并发执行此代码块,以及任何其他也需要锁定对象监视器的代码块。但是,它不会阻止执行不需要锁定对象监视器的代码的线程访问对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-16
          • 1970-01-01
          相关资源
          最近更新 更多