当前位置: 首页>编程语言>正文

基于AQS实现自定义锁CLH

public class CLHLock implements Lock {

????// 当前节点本地变量

? ?private static ThreadLocalcur curNodeLocal =new ThreadLocal<>();

// Clh 队列的尾部指针 使用 AtomicReference,方便进行CAS操作

?private AtomicReference tail = new AtomicReference<>();

public CLHLock() {

????// 设置尾部节点

? ? tail.getAndSet(Node.EMPTY);

}

//加锁操作将节点添加到等待队列的尾部

@Override

public void lock() {

????Node curNode = new Node(true, null);

? ? Node preNode =tail.get();

? ? // cas自旋 将当前节点插入到队列尾部

? ? while (!tail.compareAndSet(preNode, curNode)) {

????????preNode =tail.get();

? ? }

? ? ? ?//设置前驱

? ? curNode.setPreviewNode(preNode);

? ? //自旋监听前驱节点locked变量直到其中的值变为false

? ? // 若前继节点为true 则表示一直抢占锁

? ? while (curNode.getPreviewNode().locked) {

? ? ?// 让出cpu 提高性能

? ? ? ? Thread.yield();

? ? }

? ? //能执行到这里 获取到锁了

? ? System.out.println("获取到锁了!!!!");

? ? //将当前节点缓存到本地变量中 释放锁会用到

? ? curNodeLocal.set(curNode);

}

?// 释放锁

?@Override

public void unlock() {

Node curNode =curNodeLocal.get();

? ? curNode.setLocked(false);

? ? curNode.setPreviewNode(null); //help full gc

? ? curNodeLocal.set(null);

}

@Data

static class Node {

? ?//true:当前线程正在抢占锁、或者已经占有锁

? ? // false:当前线程已经释放锁,下一个线程可以占有锁了

? ? volatile boolean locked;

? ? //前一个节点,需要监听其 locked 字段

? ? Node previewNode;

? ? public Node(boolean locked, Node previewNode) {

? ? ? ? this.locked = locked;

? ? ? ? this.previewNode = previewNode;

? ? }

? ? ?//空节点

? ? public static final NodeEMPTY = new Node(false, null);

}

public static int sum =0;

@Test

public void testCLHLockCapability() {

? ?//每条线程执行轮数

? ? final int turns =10000;

? ? //线程数

? ? final int threads =10;

? ? //线程池模拟测试

? ? ExecutorService executorService = Executors.newFixedThreadPool(threads);

? ? CLHLock lock = new CLHLock();

? ? long start = System.currentTimeMillis();

? ? CountDownLatch countDownLatch = new ? CountDownLatch(threads);

? ? for (int i =0; i < threads; i++) {

????????executorService.submit(() ->{

? ? ? ? ? ? ? ?for (int j =0; j < turns; j++ ) {

? ? ? ? ? ? ? ? ? ? lock.lock();

? ? ? ? ? ? ? ? try {

????????????????????sum++;

? ? ? ? ? ? ? ? }? finally {

????????????????????lock.unlock();

? ? ? ? ? ? ? ? }

????????}

????????????countDownLatch.countDown();

? ? ? ? });

? ? }

try {

????????//等待倒数闩归 0,所有线程结束

? ? ? ? countDownLatch.await();

? ? } catch (InterruptedException e) {

????????e.printStackTrace();

? ? }

????float time = (System.currentTimeMillis() - start) /1000F;

? ? System.out.println("运行的时长为:" + time);

? ? System.out.println("累加结果为:" +sum);

????}

}


https://www.xamrdz.com/lan/5pd1997488.html

相关文章: