简介

临近过年了,没什么需求,今天模仿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);
}
}

模仿ReentrantLock类自定义锁的更多相关文章

  1. 模仿CountDownLatch类自定义倒时计时器

    简介 这里模仿CountDownLatch类自定义到时计时器,利用AQS模板中的尝试获得共享和释放共享 1.MyCountDownLatch package com.jacky; import com ...

  2. 深入理解独占锁ReentrantLock类锁

    ReentrantLock介绍 [1]ReentrantLock是一种基于AQS框架的应用实现,是JDK中的一种线程并发访问的同步手段,它的功能类似于synchronized是一种互斥锁,可以保证线程 ...

  3. 【腾讯Bugly干货分享】浅谈Android自定义锁屏页的发车姿势

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57875330c9da73584b025873 一.为什么需要自定义锁屏页 锁屏 ...

  4. 浅谈 Android 自定义锁屏页的发车姿势

    作者:blowUp,原文链接:http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653577446&idx=2&sn= ...

  5. ReentrantLock类的基本结构

    ReentrantLock类是一个可重入互斥锁,它具有与使用synchronized()方法和语句访问隐式监视器锁相同的基本行为和语义,但是它的功能更强大.ReentrantLock由最近成功获得锁但 ...

  6. 浅谈Android自定义锁屏页的发车姿势

    一.为什么需要自定义锁屏页 锁屏作为一种黑白屏时代就存在的手机功能,至今仍发挥着巨大作用,特别是触屏时代的到来,锁屏的功用被发挥到了极致.多少人曾经在无聊的时候每隔几分钟划开锁屏再关上,孜孜不倦,其酸 ...

  7. 【试验局】ReentrantLock中非公平锁与公平锁的性能测试

    硬件环境: CPU:AMD Phenom(tm) II X4 955 Processor Memory:8G SSD(128G):/ HDD(1T):/home/ 软件环境: OS:Ubuntu14. ...

  8. [图解Java]ReentrantLock重入锁

    图解ReentrantLock 0. demo 我先给出一个demo, 这样大家就可以根据我给的这段代码, 边调试边看源码了. 还是那句话: 注意"My" , 我把Reentran ...

  9. java中的 java.util.concurrent.locks.ReentrantLock类中的lockInterruptibly()方法介绍

    在java的 java.util.concurrent.locks包中,ReentrantLock类实现了lock接口,lock接口用于加锁和解锁限制,加锁后必须释放锁,其他的线程才能进入到里面执行, ...

随机推荐

  1. IdentityServer4-快速入门

    一.设置和概述 二.使用客户端凭证保护API 三.使用密码保护API 四.使用OpenID Connect添加用户验证 五.添加对外部认证的支持 六.切换到Hybrid Flow并添加API访问权限 ...

  2. Python3函数式编程

    Python函数式编程 函数式编程可以使代码更加简洁,易于理解.Python提供的常见函数式编程方法如下: map(函数,可迭代式)映射函数 filter(函数,可迭代式)过滤函数 reduce(函数 ...

  3. 安装 Keepalived

    安装环境 [root@node1 ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@node1 ~]# cat /proc/v ...

  4. jquery终止函数

    jQuery如何退出each循环?如何退出function函数?1.在函数内部使用return false是跳出function;在each的回调函数中使用return false,是跳出each循环 ...

  5. Linux学习笔记14—文件的压缩与打包

    1..gz   gzip 压缩工具压缩的文件 .bz2   bzip2 压缩工具压缩的文件 .tar   tar 打包程序打包的文件(tar并没有压缩功能,只是把一个目录合并成一个文件) .tar.g ...

  6. Revit API创建房间

    start [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] );             ...

  7. 移动电源、3G路由拆机

    这款电源4400mAh,淘宝也就八十元左右,可以作为无线路由使用,可以插3G网卡,总的来说还算不错,关键是外观精美,网上一堆和华美A100那样的,可惜实在太丑,这款外观虽然漂亮,但是和一百多的相比不支 ...

  8. OS面试题(转载)

    转载自:http://placement.freshersworld.com/power-preparation/technical-interview-preparation/os-intervie ...

  9. Tomcat热部署SpringMVC项目出错

    一.问题 项目照常跑,没有什么大的影响,但是在控制台却出现了错误,具体信息如下图所示 二.解决方法 原因分析:很多人已经说的很明白了,这大概是因为项目文件很多,在tomcat重启的时候,之前的tomc ...

  10. C#语言

    封面 书名 版权 前言 目录 第Ⅰ部分 C#语言 第1章  NET体系结构 1.1  C#与.NET的关系 1.2  公共语言运行库 1.2.1  平台无关性 1.2.2  提高性能 1.2.3  语 ...