欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java三种不同的锁

程序员文章站 2022-05-04 15:53:10
...
  1. Java中,锁分为乐观锁和悲观锁两类(数据库乐观锁和悲观锁参考 http://blog.csdn.net/liupeng_qwert/article/details/72935469

    悲观锁:直接将在并发情况下可能出问题的代码加同步,同一时刻只允许一个线程访问,典型的代表是synchronized
    乐观锁:每次不加锁去执行某项操作,如果发生冲突则失败并重试,直到成功为止,也称之为【自旋】
    乐观锁实现利用了CAS机制(Compare and Swap),CAS则依赖于CPU特殊指令实现

  2. 什么是CAS
    2.1 原理:“CAS有三个操作数,内存数据v,旧的预期数据A,要修改的数据B。每次进行数据更新时,当且仅当预期值A和内存中的数据V相同时,才将内存中的数据修改为B,否则什么也不做”
    2.2 哪些Java类实现利用了乐观锁(CAS)
    Java中的原子类利用了CPU的CAS机制,例如AtomicInteger、AtomicBoolean、AtomicLong、AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray,以AtomicInteger为例,查看源码实现

/**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

/**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return true if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

2.3 CAS可能出现ABA问题?

3 基于synchronized实现锁
(1) 基于JVM实现,synchronized锁即对象监视器,属于独占锁
(2) JDK1.5之前只能通过synchronized实现同步
(3) 同步代码实际上是单线程访问,效率比较低,因此同步块(block)越小越好
//例如单例模式实现中的双重校验

public class JDBCSingleton4 {
    /**
     * 构造函数私有,避免类在外部被实例化
     */
    private JDBCSingleton4(){
    }

    private static JDBCSingleton4 jdbcSingleton = null;  // 懒汉模式3,双中检查锁定,线程安全

    public  static JDBCSingleton4 getJDBCSinleton(){ // synchronized关键字不加在方法上,避免每次都要同步,显著提升性能
        if(jdbcSingleton == null){  
            synchronized(JDBCSingleton4.class){
                if(jdbcSingleton == null){
                    jdbcSingleton = new JDBCSingleton4();
                }
            }
        }
        return jdbcSingleton;
    }
}

(4) 内部原理示意图
Java三种不同的锁

4 基于lock实现锁

public class LockMethod {

    public static void main(String[] args) {
        final Table6 tObj = new Table6();   // 共享对象
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                tObj.print(5);
            }
        });

        Thread t2 = new Thread(new Runnable(){
            @Override
            public void run(){
                tObj.print(100);
            }
        });

        t1.start();
        t2.start();
    }
}

class Table6 {

    private Lock lock = new ReentrantLock();

     public void print(int n){

         try {
             lock.lock();

            for(int i=1; i<= 5; i++){
                System.out.println(n*i);
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
         } finally {
             lock.unlock();
         }
    }
}

输出结果

5
10
15
20
25
100
200
300
400
500

可以看出,没有出现线程交叉访问的情况,线程安全

5 基于CAS实现锁

相关标签: 乐观锁