zoukankan      html  css  js  c++  java
  • 实现一个java锁

    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()+" "+"正在执行..."+ 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();
    }
    }
    }
    输出结果截图如下:

    而注销掉加锁的两行,则

    效果很明显了


  • 相关阅读:
    Pro Andorid3第二章:设置开发环境
    Seminar 记录
    安装CGAL
    Literature review
    第七章:清楚简洁的英文 《英语科技写作(文法与修辞原则)》by 方克涛
    幻灯片制作去除模板背景
    vs2008下设置.h, .lib和 .dll 的路径配置全图及其意义
    配置环境变量
    PPT制作技巧
    #include文件时用双引号和尖括号的区别
  • 原文地址:https://www.cnblogs.com/hd-zg/p/11202203.html
Copyright © 2011-2022 走看看