手写JDK锁

需要三个步骤:

  1. 手写一个类MyLock,实现Lock接口

  2. 重写lock()方法

  3. 重写unlock()方法

代码:

public class MyLock implements Lock {

    //线程的原子操作类
AtomicReference<Thread> owner = new AtomicReference<>(); //如果有的线程抢不到,就放入等待队列
public LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>(); @Override
public void lock() {
//多个线程同时调用
while (!owner.compareAndSet(null, Thread.currentThread())) {//如果不成功
waiters.add(Thread.currentThread());//加入等待队列
//Thread.currentThread().wait();//不能使用,wait()方法需要synchronized关键字
LockSupport.park();//让当前线程等待
//取巧的方式:如果能执行到本行的话,说明这个线程被唤醒了,可以从等待队列中删除了
waiters.remove(Thread.currentThread());
}
} @Override
public void unlock() {
//多个线程同时解锁
if (owner.compareAndSet(Thread.currentThread(), null)) {//判断当前线程是不是owner
//释放锁
Object[] objects = waiters.toArray();//等待队列转化为数组
for (Object object : objects) {//唤醒等待队列中所有的线程
Thread thread = (Thread) object;
LockSupport.unpark(thread);
}
} } @Override
public void lockInterruptibly() throws InterruptedException {
// TODO Auto-generated method stub } @Override
public boolean tryLock() {
// TODO Auto-generated method stub
return false;
} @Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
// TODO Auto-generated method stub
return false;
} @Override
public Condition newCondition() {
// TODO Auto-generated method stub
return null;
} }

测试

启动10个线程,每个线程执行10000次incr()操作。

public class TestMyLock {
int i = 0;
int j = 0;
Lock lock = new MyLock(); public void incr() {
lock.lock();
try {
i++;
j++;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
} public static void main(String[] args) throws InterruptedException {
TestMyLock demo = new TestMyLock();
for (int k = 0; k < 10; k++) {
new Thread(() -> {
for (int i = 0; i < 10000; i++) {
demo.incr();
}
}).start();
} Thread.sleep(1000);
System.out.println(demo.i);
System.out.println(demo.j);
}
}

执行结果:

如何手写JDK锁的更多相关文章

  1. 代理模式精讲(手写JDK动态代理)

    代理模式是一种架构型模式,表现出来就是一个类代表另一个类的功能,一般用在想对访问一个类的时候做一些控制,同时又不想影响正常的业务,这种代理模式在现实的生活中应用的也非常的广泛,我用穷举法给举几个好理解 ...

  2. JUC 并发编程--05, Volatile关键字特性: 可见性, 不保证原子性,禁止指令重排, 代码证明过程. CAS了解么 , ABA怎么解决, 手写自旋锁和死锁

    问: 了解volatile关键字么? 答: 他是java 的关键字, 保证可见性, 不保证原子性, 禁止指令重排 问: 你说的这三个特性, 能写代码证明么? 答: .... 问: 听说过 CAS么 他 ...

  3. springmvc 动态代理 JDK实现与模拟JDK纯手写实现。

    首先明白 动态代理和静态代理的区别: 静态代理:①持有被代理类的引用  ② 代理类一开始就被加载到内存中了(非常重要) 动态代理:JDK中的动态代理中的代理类是动态生成的.并且生成的动态代理类为$Pr ...

  4. JDK动态代理深入理解分析并手写简易JDK动态代理(下)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...

  5. JDK动态代理深入理解分析并手写简易JDK动态代理(上)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...

  6. Zookeeper——基本使用以及应用场景(手写实现分布式锁和rpc框架)

    文章目录 Zookeeper的基本使用 Zookeeper单机部署 Zookeeper集群搭建 JavaAPI的使用 Zookeeper的应用场景 分布式锁的实现 独享锁 可重入锁 实现RPC框架 基 ...

  7. 手写阻塞队列(Condition实现)

    自己实现阻塞队列的话可以采用Object下的wait和notify方法,也可以使用Lock锁提供的Condition来实现,本文就是自己手撸的一个简单的阻塞队列,部分借鉴了JDK的源码.Ps:最近看面 ...

  8. 手写Spring事务框架

    Spring事务基于AOP环绕通知和异常通知 编程事务 声明事务 Spring事务底层使用编程事务+AOP进行包装的   = 声明事务 AOP应用场景:  事务 权限 参数验证 什么是AOP技术 AO ...

  9. 自己动手写把”锁”---LockSupport介绍

    本篇是<自己动手写把"锁">系列技术铺垫的最后一个知识点.本篇主要讲解LockSupport工具类,它用来实现线程的挂起和唤醒. LockSupport是Java6引入 ...

随机推荐

  1. Python2.7和3.5双版本共存和pip的使用

    1. Python2.7和3.5并存 1.1 安装 安装自不必多说,先装2.7,再装3.5. 说下安装的目录:Py3.5和Py2.7默认的安装目录是不一样的,按默认的来就好,不用管. Python2. ...

  2. Python 基础【二】 上

    一.python语言分类 1. C python   c语言的python版本 官方推荐 使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行 ...

  3. laravel5.5 延时队列的使用

    队列这个知识相对比较冷门,因为平时的CURD基本用不到这个知识,今天用到了,所以就写个博客记录一下吧. 首先你得清楚要用什么驱动,除了database队列驱动(选择database驱动要php art ...

  4. js基础进阶--编码实用技巧(二)

    我的个人博客:http://www.xiaolongwu.cn 接上篇文章 js编码的实用技巧(一) 5.合理利用||运算符 使用||可以作为参数之外的默认值,当第一个参数返回值为false时,那么第 ...

  5. windows下Redis的安装配置以及注意事项

    一.下载windows版本的Redis 去官网找了很久,发现原来在官网上可以下载的windows版本的,现在官网以及没有下载地址,只能在github上下载,官网只提供linux版本的下载 官网下载地址 ...

  6. Swift学习字符串、数组、字典

    一.字符串的使用 let wiseWords = "\"I am a handsome\"-boy" var emptyString = "" ...

  7. mongo Shell初体验

    mongo shell是一个MongoDB的交互式JavaScript接口.您可以使用mongo shell来查询和更新数据以及执行管理操作. 打开cmd命令行,输入mongo,就可以进入mongo ...

  8. Windows 安装 Vue

    引言 在公司 linux 环境下安装不顺利,回家在 windows 下操作感觉到一种幸福 nginx 先安装了 nginx,其实跟 vue 没关系,只是打算用它做 web 服务,此处略过 nginx ...

  9. Web开发:需收藏的JavaScript常用技巧

    原文来自:https://www.baidu.com/home/news/data/newspage?nid=4242707244478773456&n_type=0&p_from=1 ...

  10. [OPEN CV] 常用视频操作方法

    一.视频的定义 视频(Video)泛指将一系列静态影像以电信号的方式加以捕捉.纪录.处理.储存.传送与重现的各种技术.连续的图像变化每秒超过24帧(frame)画面以上时,根据视觉暂留原理,人眼无法辨 ...