Java并发编程 -- AQS入门&实现可重入锁
Java并发编程 -- AQS可能会看的一脸懵逼,今天实战一个项目练手AQS
MyAQSLock.java
/** * Created by Fant.J. */ public class MyAQSLock implements Lock { private Helper helper = new Helper(); private class Helper extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int arg) { // 如果第一个线程进来,可以拿到锁,因此我们可以返回true // 如果第二个线程进来,则拿不到锁,返回false。有种特例,如果当前进来的线程和当前保存的线程是同一个线程,则可以拿到锁,但是有代价,要更新状态值 // 如何判断是第一个线程进来还是其他线程进来? //获取状态值 int state = getState(); Thread t = Thread.currentThread(); //如果状态=0,那就是第一个线程 if (state == 0) { if (compareAndSetState(0, arg)) { //设置当前线程为独占锁线程 setExclusiveOwnerThread(t); return true; } } else if (getExclusiveOwnerThread() == t) { setState(state + 1); return true; } return false; } @Override protected boolean tryRelease(int arg) { // 锁的获取和释放肯定是一一对应的,那么调用此方法的线程一定是当前线程 //获取当前线程,如果不等于独占锁的线程 if (Thread.currentThread() != getExclusiveOwnerThread()) { throw new RuntimeException(); } int state = getState() - arg; boolean flag = false; if (state == 0) { setExclusiveOwnerThread(null); flag = true; } setState(state); return flag; } Condition newCondition() { return new ConditionObject(); } } @Override public void lock() { helper.acquire(1); } @Override public void lockInterruptibly() throws InterruptedException { helper.acquireInterruptibly(1); } @Override public boolean tryLock() { return helper.tryAcquire(1); } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return helper.tryAcquireNanos(1, unit.toNanos(time)); } @Override public void unlock() { helper.release(1); } @Override public Condition newCondition() { return helper.newCondition(); } }
从上往下分析,首先继承Lock接口,然后定义一个子类为非公共内部帮助器类Helper类,Helper类继承AQS,重写它的tryAcquire和tryRelease方法。作为锁的获取和释放。然后填充Lock的子类实现。(为什么Lock子类方法里传值都是1呢,因为AQS源码就是这样,1一路传到底),注释还算详细,就不在这多说了。
/** * Created by Fant.J. */ class TestAQS { private int value; private MyAQSLock myAQSLock = new MyAQSLock(); public int next(){ myAQSLock.lock(); try { Thread.sleep(300); return value++; } catch (InterruptedException e) { throw new RuntimeException(); }finally { myAQSLock.unlock(); } } public void a() { myAQSLock.lock(); System.out.println("a"); b(); myAQSLock.unlock(); } public void b() { myAQSLock.lock(); System.out.println("b"); myAQSLock.unlock(); } public static void main(String[] args) { TestAQS test = new TestAQS(); new Thread(new Runnable() { @Override public void run() { test.a(); } }).start(); new Thread(new Runnable() { @Override public void run() { while (true){ System.out.println(Thread.currentThread().getName()+" "+test.next()); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true){ System.out.println(Thread.currentThread().getName()+" "+test.next()); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true){ System.out.println(Thread.currentThread().getName()+" "+test.next()); } } }).start(); } }
开了四个线程,一个线程去跑a方法,a方法中调用b方法,a、b方法调用之前都有加锁,之后有解锁,这个线程用来做可重入锁的测试,其他三个线程是测试线程安全。
结果图
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Python高级进阶(一)Python框架之Django入门
传说中的Django Django由来 Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的框架模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。Django的作者不是一个人而是一个团队(点击 Django Team了解团队成员),我们都知道Django是以一个人的名字命名的,就是下面这个人,我们就叫他“三指琴魔”强哥吧 Django的设计思路 Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don't Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。 Django采用MTV开发模式 Django是一个基于MVC构造的框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模...
- 下一篇
题解 P1255 【数楼梯】
题目链接 好吧,承认python 轻松水过代码奉上: n = int(input()) #定义,输入 a=1 #初始的变量赋值 b=1 n-=1 #我的毒瘤的循环不得不加上这句话 if n > 0 : #判断,第6,7很坑的 while n>0 : c=a+b a=b b=c n-=1 print(b) elif n == 0 : #判断边界 print(a) else : a-=1 #判断边界 print(a) #程序拜拜
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题