Category: java

  • java锁机制介绍

    java锁 乐观锁与悲观锁 乐观锁与悲观锁都是一种锁机制。用于实现线程同步机制。 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。适用于数据频繁修改的场景。 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。 java中的锁机制 synchronized 在java5之前,使用关键字synchronized修饰一个方法或者代码块对临界资源的保护实现多线程并发同步。有四种不同的同步块: 实例方法 静态方法 实例方法中的同步块 静态方法中的同步块 synchronized(lockObject) { //需要访问的临界资源 } ReentrantLock Java5 java.util.concurrent.locks 提供了Lock接口。Lock提供了更加灵活的锁实现。写法一般如下: lock.lock(); try { //需要访问的临界资源 } finally { lock.unlock(); } 获取锁的方式: lock() 阻塞持续等待直到获取锁 tryLock() 方式获得锁,默认不阻塞,不等待,如果能够获取锁返回true,可以设置等待时间。 lockInterruptibly() 中断锁, 使用中断锁在等待获取锁的时候,会响应线程中断。 在Java1.5中,synchronized是一个重量级操作,需要调用操作系统相关接口,性能是低效的,有可能给线程加锁消耗的时间比有用操作消耗的时间更多。到了Java1.6,synchronized进行了很多的优化,有适应自旋、锁消除、锁粗化、轻量级锁及偏向锁等,效率有了本质上的提高。在之后推出的Java1.7与1.8中,均对该关键字的实现机理做了优化。 两种锁在低并发的情况下性能都差不多,更推荐使用synchronized,毕竟不用怕忘记在finnaly中执行unlock()。 但在高并发量的条件下,synchronized性能会迅速下降几十倍,因为多了很多自旋锁操作,而ReentrantLock的性能却能依然维持一个水准。 当线程通过synchronized等待锁时是不能被Thread.interrupt()中断的 Semaphore 使用方法与ReentrantLock相似。 acquire()方法默认为可响应中断锁,与ReentrantLock.lockInterruptibly()作用效果一致。 支持多个临界资源,而ReentrantLock只支持一个临界资源 Atom系列原子类 public class AtomicInteger extends Number […]