java手动实现简易可重入锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_33641359/article/details/87929232

 说到可重入锁默认提到的就是Reentrantlock,可重入的概念就是,当前线程可以多次获得一个锁,这样主要是解决了死锁问题。

如果没有可重入锁,当一个线程递归获得当前锁的时候,会由于锁没有释放而导致死锁,jdk基于AQS实现,主要是有个 state变量,如果是当前线程获得锁,就自增一次,释放锁就是给这个state递减,减到零就释放这个锁。这篇文章只实现非公平的可重入锁,没有涉及CLH等待队列。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by qiuyunjie .
 */
public class Test {

    public static void main (String[] args){

            //新建lock
            MyLock lock = new MyLock();
            Test1 test1 = new Test1();
            //线程一
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test1.m1(lock);
                }
            }).start();
            //线程二
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //获取锁之前先休眠一秒确保线程一先获得锁
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.lock();
                    System.out.println("别的线程获取锁");
                    lock.unlock();

                }
            }).start();


    }
}

//自定义锁类
class MyLock{
    
    //记录当前获的锁的线程
    Thread lock = null ;
    //记录重入次数
    int state = 0 ;

    //锁标志
    boolean isLocked = false ;


    //这里应该用CAS 偷懒就用synchronized
    public synchronized void lock(){

        Thread currentThread = Thread.currentThread() ;

        //不是第一个进来,并且不是当前线程就等待
        while(isLocked && lock != currentThread){
            try {
                //等待
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //是当前线程或者 第一次进来的线程就获取到锁
        isLocked = true ;
        lock = currentThread ;

        //获取到几次就加几次
        state ++ ;


    }


    public synchronized void unlock(){

        //不是当前线程就不能释放锁
        if(lock == Thread.currentThread()){
            state -- ;
            if(state == 0){
                notify();
                isLocked = false ;
            }
        }
    }







}
//测试类
class Test1{


    public void m1(MyLock lock){
        lock.lock();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("第一次进来");
        m2(lock);
        lock.unlock();
    }
    public void m2(MyLock lock){
        lock.lock();
        System.out.println("第二次进来");
        lock.unlock();

    }

}

猜你喜欢

转载自blog.csdn.net/sinat_33641359/article/details/87929232