【问题标题】:lock() method acquires locks on which object?lock() 方法获取哪个对象的锁?
【发布时间】:2016-11-20 09:25:52
【问题描述】:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    Lock lck=new ReentrantLock();

    public void lockIt(){
        lck.lock();

        for(int i=0;i<10;i++) {
            System.out.println("i : "+ i);
            try{Thread.sleep(200);} catch (Exception e){}
        }
        lck.unlock();
    }

    public void test()
    {
        synchronized(this)     **// mark 1**
        {
            for(int j=0;j<10;j++)
            {
                System.out.println("val is"+j);
                try{Thread.sleep(200);}catch (Exception e){}
            }
        }
    }

    public static void main(String[] args) {
        LockTest obj=new LockTest();
        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.lockIt();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.test();
            }
         }).start();

     }
}

} // 在上述情况下,当我们说 lck.lock();然后获取锁 实际上是哪个对象?是“this”还是“lck”本身?

即使在“this”或“lck”对象上获得了锁 那么差异如何。线程能够进入临界区 被同一个“this”或“lck”对象锁定。

案例 1:当我们在 mark1 使用 synchronized(this) 时.. 情况 2:当我们在标记 1 处使用 synchronized(lck ) 时..

在这两种情况下,两个循环都并行运行。

【问题讨论】:

  • 看看winterbe.com/posts/2015/04/30/…。您的问题的答案是 lock 方法确保锁定的块只能由一个线程访问。它实际上并没有锁定实际的object,因此synchronized 是一种不同的方法。

标签: java concurrency locks


【解决方案1】:

lck.lock()获得的锁(在lck对象上)与synchronized(this)synchronized(lck)获得的锁完全无关。

如果你想保护临界区,那么所有线程都必须使用相同的锁定机制(和相同的锁)。

java.util.concurrent.locks.Lock 是针对synchronized 关键字不够灵活的情况引入的不同机制。特别是,synchronized 关键字在执行进入和离开块时自动获取和释放锁。不可能在一种方法中获得锁,将其存储在某个地方,离开该方法并稍后释放锁。使用Lock 对象,您可以做这些事情(它还提供锁定等待超时,而synchronized 可能会永远阻塞)。

【讨论】:

    【解决方案2】:

    @Thilo 已经回答了大部分,只是在你的代码中加一点,确保你在finally块中解锁如下图,否则你有可能会被以死锁告终。

    public void lockIt(){
        lck.lock();
      try {
        for(int i=0;i<10;i++) {
            System.out.println("i : "+ i);
            try{Thread.sleep(200);}catch (Exception e){}
        }
      } finally { //important
        if(lck != null) {
            lck.unlock();
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多