简单锁类

package com.fangshirui;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;

/**
 * 简单锁的实现
 *
 * @author fangshirui
 */
public class SimpleLock {

    /**
     * 要借助AtomicReference提供的CAS方法支持原子性,而且AtomicReference中的value
     * 已经加了volatile实现不同线程的可见性,最终实现线程安全。
     */
    private final AtomicReference<Thread> owner = new AtomicReference<>();

    /**
     * 阻塞队列
     */
    private final LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();


    /**
     * 争夺锁方法
     */
    public void lock() {
        while (!tryLock()) {
            waiters.add(Thread.currentThread());
            // 将当前线程阻塞
            LockSupport.park();
        }

        waiters.remove(Thread.currentThread());
    }

    public boolean tryLock() {
        // if owner.value == null , then  make owner.value = currentThread
        // 内存语义: 获取锁方法 == CAS更新volatile变量
        // 禁止重排序、将写缓冲区所有数据刷新到主内存中 ==> 内存屏障
        // 在刷新volatile变量前,会将本地所有共享变量置为无效,重新从主内存中获得。
        return owner.compareAndSet(null, Thread.currentThread());
    }

    /**
     * 释放锁
     */
    public void unlock() {
        // 内存语义: 释放锁方法 == CAS更新volatile变量
        // 禁止重排序、将写缓冲区所有数据刷新到主内存中  ==> 内存屏障
        // 在刷新volatile变量前会将本地内存所有共享变量全部刷新到主内存中。
        if (owner.compareAndSet(Thread.currentThread(), null)) {
            if (!waiters.isEmpty()) {
                // 将线程池中所有线程都激活,他们会争抢锁
                waiters.forEach(LockSupport::unpark);
            }
        }
    }
}

客户端使用

package com.fangshirui;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author fangshirui
 */
public class LockTest {
    private int i = 0;

    SimpleLock myLock = new SimpleLock();

    private void add(){
        myLock.lock();
        try{
            i++;
        }finally {
            myLock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        LockTest lockTest = new LockTest();
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 4; i++) {
            executorService.submit(() ->{
                for (int j = 0; j < 10000; j++) {
                    lockTest.add();
                }
            });
        }

        Thread.sleep(2000);
        System.out.println(lockTest.i);
        executorService.shutdown();
    }
}


输出:
40000

不使用简单锁,而使用内置的原子类AtomicInteger

package com.fangshirui;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author fangshirui
 */
public class LockTest {
    private final AtomicInteger i = new AtomicInteger(0);

    private void add(){
        i.addAndGet(1);
    }

    public static void main(String[] args) throws InterruptedException {
        LockTest lockTest = new LockTest();
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 4; i++) {
            executorService.submit(() ->{
                for (int j = 0; j < 10000; j++) {
                    lockTest.add();
                }
            });
        }

        Thread.sleep(2000);
        System.out.println(lockTest.i.get());
        executorService.shutdown();
    }
}

输出:
40000
最后修改:2021 年 04 月 29 日
如果觉得我的文章对你有用,请随意赞赏