ReentrantLock代替synchronized手动上锁,trylock尝试上锁,lockInterruptibly设定该锁可以打断,实现公平锁

1.Reentrantlock是手动锁,重入锁,可以来代替synchronized

synchronized的使用方法如下:

public class T(){
    public synchronized void m1(){
        //
    }
    public synchronized void m2(){
        //
    }
    public static void main(String[] args){
        T t=new T();
        new Thread(t::m1).start();
        new Thread(t::m2).start();
        //程序在执行过程中,第一个线程得到了t的锁,第二个线程执行时,也想得到t的锁。只能等第一个线程将锁释放。
    }
}

用Reentrantlock代替synchronized,用法如下,千万注意:手动上锁,必须手动解锁。

Lock lock = new Reentrantlock();//首先实例化一个锁lock
public void m1(){
    lock.lock();//手动上锁,相当于synchronized(this)
    try{
        //上锁之后执行线程内容
        //~~~~
    }catch(InterruptedException e){
        e.printStrackTrace;
    }finally{
        //手动锁最重要的是必须手动释放锁
        //与synchronized不同的是,sync出现异常,默认自动释放锁。而Reentrantlock必须手动释放。
        lock.unlock();
    }
}
//Reentrantlock必须有finally释放锁
public void m2(){
    lock.lock();//手动上锁,相当于synchronized(this)
    try{
        //上锁之后执行线程内容
        //~~~~
    }catch(InterruptedException e){//延时的时候可能出现的异常
        e.printStrackTrace;
    }finally{
        lock.unlock();
    }
}
//如果想让两个方法互斥的话,锁定同一把锁就好了
2.与sync不同的是,Reentrantlock可以尝试上锁

synchronized上锁是同步方法没有执行完的时候,其他线程想执行这段同步方法必须一直等待锁的释放。
而Reentrantlock可以尝试上锁,如果在一定时间内都没有申请到锁,那么选择等待或执行其他任务。Reentrantlock有更多的选择。
示例代码:

public class ReLockTest {
    Lock lock =new ReentrantLock();
    public void m1(){
        try {
            lock.lock();
            System.out.println("m1 start");
            for(int i=0;i<6;i++){
                System.out.println("add"+i);
                TimeUnit.SECONDS.sleep(1);
            }
            System.out.println("m1 end");
        }catch(InterruptedException e){
             e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void m2(){
        try{
            boolean isLOCK=lock.tryLock();//先尝试能否得到锁
            System.out.println("isLOCK:"+isLOCK);//isLOCK:false
            TimeUnit.SECONDS.sleep(10);//10s之后再尝试
            isLOCK=lock.tryLock();
            System.out.println("isLoCK:"+isLOCK);//isLoCK:true
        }catch(InterruptedException e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ReLockTest r1=new ReLockTest();
        new Thread(r1::m1).start();
        new Thread(r1::m2).start();
    }
}

并且trylock可以设定申请锁的时限,比如:

//改进代码,trylock可以设置try时间(时间长度,时间单位)
public void m2(){
    boolean isLOCK=false;
    try{
        isLOCK=lock.tryLock(10,TimeUnit.SECONDS);
        System.out.println("isLOCK:"+isLOCK);
    }catch(InterruptedException e){
        e.printStackTrace();
    }finally{
        if(isLOCK)lock.unlock();//要注意trylock释放锁的时候,如果申请到了锁,再释放锁。
    }
}

trylock为true指的是,刚刚获取到锁,或已经占有了锁

3.可以用lockInterruptibly()设定锁是可以打断的

补充一个m3方法如下:

public void m3(){
    try{
        System.out.println("this is m3"+lock.tryLock());//false,说明一开始线程2没有申请到锁
        lock.lockInterruptibly();//对interrupt()方法做出响应,会抛出异常被catch,后面的代码不执行。
        System.out.println("this is m3"+lock.tryLock());
        TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
    }catch(InterruptedException e){
        System.out.println("m3 interrupted");
    }finally {
        //lockInterruptibly()方法不确定能不能申请到锁。
        //所以要释放锁的时候先判断有没有申请到锁
        if(lock.tryLock())lock.unlock();
    }
}
public static void main(String[] args) {
        ReLockTest r1=new ReLockTest();
        //在main函数里面,开启线程1,获得锁。
        new Thread(r1::m1).start();
        //如果开启线程2,是申请不到锁的。
        Thread t2=new Thread(r1::m3);
        t2.start();
        try{
            //主线程延时5秒钟之后,将t2线程打断
            TimeUnit.SECONDS.sleep(5);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        t2.interrupt();
    }

执行结果为:

m1 start
add0
this is m3false
add1
add2
add3
add4
m3 interrupted//这里可以看到线程1在执行的过程中,线程2申请锁,失败,延时之后,线程2 被打断
add5
m1 end
Reentrantlock还可以作为公平锁
public static Lock lock=new Reentrantlock(true);//当加上参数true的时候,指定是公平锁。

Reentrantlock还可以指定为公平锁。synchtonized默认是非公平锁。也就是说,当一个线程释放锁之后,其他的线程哪个先得到锁是不确定的。
公平锁会根据等待时间,让等待时间更久的得到这把锁。但是公平锁效率比较低。

原创文章 64 获赞 27 访问量 9422

猜你喜欢

转载自blog.csdn.net/weixin_44893585/article/details/104581418