博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模仿ReentrantLock类自定义锁
阅读量:6268 次
发布时间:2019-06-22

本文共 5098 字,大约阅读时间需要 16 分钟。

简介

  临近过年了,没什么需求,今天模仿ReentrantLock自定义写了一个自己锁,在这里记录一下,前提是对AQS原理有所了解,分享给大家

1、自定义锁MyLock

package com.jacky;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.AbstractQueuedSynchronizer;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;/** * Created by jacky on 2018/2/12. */public class MyLock implements Lock{    private final Sync sync;    /**     * 创建公平锁或非公平锁     * @param fairFlag     */    public MyLock(boolean fairFlag){       sync = fairFlag ? new FairSync() : new NonFairSync();    }    /**     * 默认是公平锁     */    public MyLock(){        sync = new FairSync();    }    /**     * 获取锁     */    @Override    public void lock() {         sync.acquire(1);    }    /**     * 获取可中断锁     * @throws InterruptedException     */    @Override    public void lockInterruptibly() throws InterruptedException {        sync.acquireInterruptibly(1);    }    /**     * 它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,     * 也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待     * @return     */    @Override    public boolean tryLock() {        return sync.nonfairTryAcquire(1);    }    /**     * 获得可超时的锁     * @param time     * @param unit     * @return     * @throws InterruptedException     */    @Override    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {        return sync.tryAcquireNanos(1,unit.toNanos(time));    }    /**     * 释放锁     */    @Override    public void unlock() {        sync.release(1);    }    @Override    public Condition newCondition() {        return sync.new ConditionObject();    }    abstract static class Sync extends AbstractQueuedSynchronizer {        /**         * 判断当前线程是否获得锁         * @return         */        @Override        protected boolean isHeldExclusively() {            return Thread.currentThread() ==getExclusiveOwnerThread();        }        /**         * 尝试释放锁         * @param arg         * @return         */        @Override        protected boolean tryRelease(int arg) {            int newState =getState()-arg;            setState(newState < 0 ? 0:newState);            if (newState ==0){                setExclusiveOwnerThread(null);            }            return true;        }        final boolean nonfairTryAcquire(int arg) {            Thread thread = Thread.currentThread();            int state = getState();            if (state ==0){                compareAndSetState(0,state+arg);                //设置独占线程                setExclusiveOwnerThread(thread);                return true;            }            if (isHeldExclusively()){                setState(state+arg);                return true;            }            return false;        }    }    static class FairSync extends Sync{        /**         * 尝试公平锁获得锁         * @param arg         * @return         */        @Override        public boolean tryAcquire(int arg) {            Thread thread = Thread.currentThread();            int state = getState();            if (state ==0){                //判断队列是否有数据,有数据就返回获取锁失败(公平锁才会这么做)                if (hasQueuedPredecessors()){                    return false;                }                compareAndSetState(0,state+arg);                //设置独占线程                setExclusiveOwnerThread(thread);                return true;            }            if (isHeldExclusively()){                setState(state+arg);                 return true;            }            return false;        }    }    static class NonFairSync extends Sync{        @Override        public boolean tryAcquire(int arg) {            return  nonfairTryAcquire(arg);        }    }}

2、测试类

package com.jacky;import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;import java.util.concurrent.CountDownLatch;import java.util.concurrent.locks.ReentrantLock;/** * Created by jacky on 2018/2/12. */public class MyLockDemo {    private final static MyLock lock = new MyLock(false);    //private final static ReentrantLock lock = new ReentrantLock(true);    private static int num = 0;    public static void main(String[] args) {        int count = 2000;        CountDownLatch countDownLatch = new CountDownLatch(count);        Runnable runnable = new Runnable() {            @Override            public void run() {                try {                    lock.lock();                Thread thread = Thread.currentThread();                System.out.println("--start--"+thread.getName());                try {                    Thread.sleep(1);                } catch (InterruptedException e) {                    e.printStackTrace();                }                num++;                System.out.println("--end--");                countDownLatch.countDown();                }finally {                   lock.unlock();                }            }        };        Thread thread = null;        for (int i = 0; i < count; i++) {            thread = new Thread(runnable,"t"+i);            thread.start();        }        try {            countDownLatch.await();        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("--num--"+num);    }}

 

转载地址:http://yippa.baihongyu.com/

你可能感兴趣的文章
JavaScript编码encode和decode escape和unescape
查看>>
ppp点对点协议
查看>>
html5游戏开发-简单tiger机
查看>>
Codeforces 712C Memory and De-Evolution
查看>>
编写的windows程序,崩溃时产生crash dump文件的办法
查看>>
Ural2110 : Remove or Maximize
查看>>
Django REST framework 的TokenAuth认证及外键Serializer基本实现
查看>>
《ArcGIS Runtime SDK for Android开发笔记》——问题集:如何解决ArcGIS Runtime SDK for Android中文标注无法显示的问题(转载)...
查看>>
Spring Boot日志管理
查看>>
动态注册HttpModule管道,实现global.asax功能
查看>>
使用 ES2015 编写 Gulp 构建
查看>>
[转]Using NLog for ASP.NET Core to write custom information to the database
查看>>
BZOJ 4766: 文艺计算姬 [矩阵树定理 快速乘]
查看>>
MySQL 的instr函数
查看>>
Hibernate的核心对象关系映射
查看>>
接口与抽象类的使用选择
查看>>
if __name__ == '__main__'
查看>>
CF 375D. Tree and Queries【莫队 | dsu on tree】
查看>>
Maven最佳实践 划分模块 配置多模块项目 pom modules
查看>>
Hadoop学习笔记——WordCount
查看>>