JAVA Synchronized 与 Lock接口的区别

  • synchronized

  1. 关于synchronized字段,无论该关键字是修饰方法仍是修饰同步代码块,synchronzed拿到的都是对象。
  2. 当synchronized修饰的是方法时,synchronized所拿到的是调用该方法的对象的锁,通常状况下都是this的锁;
  3. 当synchronized修饰的静态方法时,因为静态方法不包含this,属于类层次的方法,因此,synchronized拿到的是这个方法所属Class对象的锁。
  4. synchronized锁属于JAVA语言特性,JVM会自动释放不须要用户操做,所以不会致使死锁现象发生。
  • synchronized锁释放时通常是如下三种状况:
  1.  占有锁的线程执行完了代码块,而后释放对锁的占有;
  2.  占有锁的线程发生了异常,此时JVM会让线程自动释放锁;
  3. 占有锁的线程调用了wait()方法,从而进入了WAITING状态须要释放锁。
  • lock接口

  1. 而Lock接口须要用户手动释放,在发生异常时,若是没有主动经过unLock()去释放锁,则极可能形成死锁现象,所以使用Lock时须要在finally块中释放锁;如:finally { lock.unlock(); }
  2. Lock可让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不可以响应中断;
  3. 经过Lock能够知道有没有成功获取锁,而synchronized却没法办到。如lock.tryLock()
  4. Lock能够提升多个线程进行读操做的效率,如ReentrantReadWriteLock
  5. 在性能上来讲,若是竞争资源不激烈,二者的性能是差很少的,而当竞争资源很是激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。因此说,在具体使用时要根据适当状况选择。
  • 锁的相关概念介绍

  1. 可重入锁,synchronized和ReentrantLock都是可重入锁,当一个线程执行到某个synchronized方法时,好比说method1,而在method1中会调用另一个synchronized方法method2,此时线程没必要从新去申请锁,而是能够直接执行方法method2。由于如以前所说syncchronized所拿到的是调用该方法的对象的锁是this锁,即MyClass类的对象,因此调用method2不须要从新得到锁。假如synchronized不具有可重入性,此时线程A须要从新申请锁。可是这就会形成一个问题,由于线程A已经持有了该对象的锁,而又在申请获取该对象的锁,这样就会线程A一直等待永远不会获取到的锁。
    class MyClass {
        public synchronized void method1() {
            method2();
        }
         
        public synchronized void method2() {
             
        }
    }
相关文章
相关标签/搜索