AQS是实现java锁的核心,但是实现起来还是仅仅只需继承该类重写它的几个主要方法即可。

1.首先,定义一个同步类,继承AQS。

//这里要有个Sync内部类,实现锁需要继承AQS
private static class MySync extends AbstractQueuedSynchronizer {
/**
* 使用CAS尝试改变同步状态,抢锁就使用cas将当前线程设置状态为1,设置owner为当前线程
* @param arg 设置状态锁必须要设置为1
* @return
*/
@Override
protected boolean tryAcquire(int arg) {
if(arg !=1){
throw new RuntimeException("args 不为1");
}
//使用CAS尝试改变同步状态
if(compareAndSetState(0,1)){
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
} /**
* 释放锁不需要cas操作
* @param arg
* @return
*/
@Override
protected boolean tryRelease(int arg) {
if(getState()==0){
throw new IllegalMonitorStateException();
}
//设置锁不被任何线程持有
setExclusiveOwnerThread(null);
setState(0);
return true;
} @Override
protected boolean isHeldExclusively() {
return getState()==1;
}
}
2.要实现锁,自然要定义我自己的锁了,如下
/**
* 手动是实现java的锁机制
* 这里主要要实现几个方法:tryLock,lock,unlock
*/
public class MyLock implements Lock {
  
  //这里引用刚才的aqs子类
private MySync mySync=new MySync(); @Override
public void lock() {
mySync.acquire(1);
} @Override
public boolean tryLock() {
return mySync.tryAcquire(1);
} @Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return mySync.tryAcquireNanos(1,time);
} @Override
public void unlock() {
mySync.release(1);
} @Override
public Condition newCondition() {
return null;
}
@Override
public void lockInterruptibly() throws InterruptedException { }
}
好了,仅仅两个类即可搞定。下面来测试下是否好使。先定义一个线程,使用自己实现的锁
public class MyThread implements Runnable{

    MyLock myLock = new MyLock();
@Override
public void run() {
try {
myLock.lock();
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"\t"+"正在执行..."+ DateUtil.now());
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
myLock.unlock();
} }
} 最后,测试类如下,我们开启10个线程小试一把,
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread(); for (int i = 0; i < 10; i++) {
new Thread(myThread,i+"-thread").start();
}
}
}
输出结果截图如下:

而注销掉加锁的两行,则

效果很明显了

最新文章

  1. 【Android】命令行jarsigner签字和解决找不到证书链错误
  2. php学习笔记之wamp安装配置
  3. Android判断当前系统时间是否在指定时间的范围内(免消息打扰)
  4. js学习笔记6----作用域及解析机制
  5. android textview 设置text 字体
  6. PHP 表单提交多行数据,显示多个submit
  7. esriSRGeoCS2Type Constants
  8. ios7去除手势滑动返回
  9. JAVA入门[11]-jsp几点基础语法
  10. 51 Nod 1057 N的阶乘【Java大数乱搞】
  11. Linux常用命令(第二版) --权限管理命令
  12. Charles使用心得总结
  13. ABP入门系列之3——创建实体/Code First创建数据表
  14. Vmware Workstation添加centos 7系统网络问题(无IP情况)
  15. mac Navicat 破解+汉化(亲测可用)
  16. 使用dd备份和恢复ASM中的数据文件头
  17. 【BZOJ1417】Pku3156 Interconnect
  18. DragonBones的下载和安装
  19. Linux下使用timedatectl命令时间时区操作详解
  20. Unity调用Windows弹框、提示框(确认与否,中文)

热门文章

  1. C++的map用法
  2. js中call,apply,bind方法的用法
  3. Vuejs组件基础
  4. BDD的概念
  5. 修改Docker容器启动配置参数
  6. win10+py3.6+cuda9.0安装pytorch1.1.0
  7. unity EditorGUILayer绘制报错
  8. Gamma阶段第四次scrum meeting
  9. [2019BUAA软件工程]个人期末总结感想
  10. MORMOT REST文件上传