JAVA实现自己的独占锁,并可重入

1。写一个自己的锁

 

package lock.mylock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * 实现自己的独占锁
 * @author Administrator
 *
 */
public class SelfLock implements Lock {

    //定义一个内部类,自定义同步器
    private static class Sync extends AbstractQueuedSynchronizer{
        
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        // 判定当前线程是否处于占用锁的状态
        @Override
        protected boolean isHeldExclusively() {
            //其实这里只需要返回当前的state状态是否为1,1表示已经获取到锁,0则表示没有获取到
            return getState()==1;
        }
        
        //实现获得锁方法
        @Override
        protected boolean tryAcquire(int arg) {
            //compareAndSetState();使用CAS设置当前状态,该方法能够保证状态设置的原子性。
            // 这个方法的实现需要查询当前状态是否允许获取,然后再进行获取(使用compareAndSetState来做)
            //如果compareAndSetState的返回值为TRUE,说明state修改成功并且成功获得了锁
            //@1参数期望值 
            //@2参数更新新值
            if(compareAndSetState(0, 1)){
                //把当前拿到锁的线程设定为当前线程,表示独占这个锁
                //判断成功后设置排他,表示当前这个锁我拿到了
                setExclusiveOwnerThread(Thread.currentThread());
                //表示当前拿到了这把锁
                return true;
            }
            //判断是否是自己拿的锁,用于重入情况
            else if(getExclusiveOwnerThread()==Thread.currentThread()){
                //如果是就+1
                setState(getState()+1);
                return true;
            }
            //那么大部分线程拿锁不成功返回false,没有拿到锁的线程返回false继续返回队列进行排队
            return false;
        }
        
        //实现释放锁方法
        @Override
        protected boolean tryRelease(int arg) {
            //判断重入的情况,如果当前线程不是我自己就抛出异常
            if(getExclusiveOwnerThread()!=Thread.currentThread()){
                throw new IllegalMonitorStateException();
            }
            if(getState() ==0){
                //如果状态为0说明状态是异常的,则抛出错误
                throw new IllegalMonitorStateException();
            }
        
            //设置状态-1
            setState(getState()-1);
            
            //如果减1了之后是0 了,说明没有线程访问,把当前拿锁的线程置为null
            if(getState()==0){
                //如果没有抛出异常则手动释放
                setExclusiveOwnerThread(null);
            }
        
            return true;
        }
         
    }
     
    // 仅需要将操作代理到Sync上即可
    private final Sync sync = new Sync();
    @Override
    public void lock() {
        System.out.println(Thread.currentThread()+" read get lock");
        sync.acquire(1);
        System.out.println(Thread.currentThread().getName()+" already got lock");
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        // TODO Auto-generated method stub
        
    }

    @Override
    public Condition newCondition() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean tryLock() {
        // TODO Auto-generated method stub
        return sync.tryAcquire(1);
    } 

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void unlock() {
        System.out.println(Thread.currentThread()+" read release lock");
        sync.release(1);
        System.out.println(Thread.currentThread().getName()+" already release lock");
    }

}
 

2.测试自己的锁

package lock.mylock;

import java.util.concurrent.locks.Lock;

import lock.mycountdownlatch.MySelfLock;
import util.SleepTools;

public class TestMyLock {

    public void test(){
        //创建一个自己的锁对象
        final Lock lock = new SelfLock();
        //写一个方法局部类继承线程
        class Worker extends Thread{
            @Override
            public void run() {
                //拿锁后打印
                lock.lock();
                System.out.println(Thread.currentThread().getName());
                try{
                    SleepTools.second(1);
                }finally {
                    //做完事情后解锁
                    lock.unlock();
                }
            }
        }
        
        //4个线程执行
        for(int i = 0 ; i < 10 ; i ++){
            Worker w = new Worker();
            w.start();
        }
        
    }
    
    public static void main(String[] args) {
        TestMyLock testMyLock = new TestMyLock();
        testMyLock.test();        
    }
    
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值