【Java并发编程】Reentrantlock(一):基本使用及特性方法

1.Reentrantlock 基本使用

reentrantlock 用于替代 synchronized,需要注意的是,必须要必须要必须要手动释放锁(重要的事情说三遍)

PS:使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放

public class ReentrantLock1 {
    
    

    ReentrantLock lock = new ReentrantLock();

    void m1(){
    
    
        lock.lock();
        for(int i=0;i<10;i++)
        System.out.println(i);
        lock.unlock();
    }

    void m2(){
    
    
        lock.lock();
        try {
    
    
            System.out.println("m2 Start!");
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }

    }

    public static void main(String[] args) {
    
    
        ReentrantLock1 reentrantLock1 = new ReentrantLock1();
        new Thread(()->reentrantLock1.m1()).start();
        new Thread(()->reentrantLock1.m2()).start();
    }
}

2.公平锁

ReentrantLock 还可以指定为公平锁

public class ReentrantLock2 {
    
    
	
	// 参数为true表示为公平锁,请对比输出结果
    ReentrantLock lock = new ReentrantLock(true); 

    void m1(){
    
    

        for(int i = 0;i<100;i++){
    
    
            this.lock.lock();
            System.out.println(Thread.currentThread().getName()+"获得锁。。");
            lock.unlock();
        }

    }

    public static void main(String[] args) {
    
    
        ReentrantLock2 reentrantLock2 = new ReentrantLock2();
        new Thread(()->reentrantLock2.m1(),"t1").start();
        new Thread(()->reentrantLock2.m1(),"t2").start();
    }
}

3.tryLock

使用 reentrantlock 可以进行“尝试锁定” tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待。

使用 tryLock 进行尝试锁定,不管锁定与否,方法都将继续执行,可以根据 tryLock 的返回值来判定是否锁定。也可以指定 tryLock 的时间,由于 tryLock(time) 抛出异常,所以要注意 unclock 的处理,必须放到 finally 中。

public class ReentrantLock3 {
    
    

    ReentrantLock lock = new ReentrantLock();

    void m1(){
    
    
        this.lock.lock();

        try {
    
    
            System.out.println("m1 start...");
            TimeUnit.SECONDS.sleep(5);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            System.out.println("别急m1完了。。");
            this.lock.unlock();
        }
    }

    void m2(){
    
    
        boolean lock = false;
        try {
    
    
            lock = this.lock.tryLock(3, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName()+"拿到锁了。");
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if(lock){
    
    
                this.lock.unlock();
            }
            System.out.println("m2不等了!!!");
        }

    }

    public static void main(String[] args) {
    
    
        ReentrantLock3 reentrantLock3 = new ReentrantLock2();
        new Thread(()->reentrantLock3.m1()).start();
        new Thread(()->reentrantLock3.m2()).start();
        new Thread(()->{
    
    
            for(int i=1;i<=5;i++){
    
    
                try {
    
    
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(i+"s");
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

4.lockInterruptibly

使用 ReentrantLock 还可以调用 lockInterruptibly 方法,可以对线程 interrupt 方法做出响应。在一个线程等待锁的过程中,可以被打断

public class ReentrantLock4 {
    
    

    public static void main(String[] args) {
    
    

        ReentrantLock lock = new ReentrantLock();

        new Thread(()->{
    
    
            try {
    
    
                lock.lock();
                System.out.println("t1 start...");
                try {
    
    
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println("t1 stop");
            } catch (Exception e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                lock.unlock();
            }

        },"t1").start();

        Thread t2 = new Thread(()->{
    
    
            System.out.println("t2想要拿锁!");
            try {
    
    
                lock.lockInterruptibly();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }finally {
    
    
                System.out.println("鸭,没拿到锁。。。不要了!!!");
                if(!lock.isLocked()){
    
    
                    lock.unlock();
                }
            }
        },"t2");
        t2.start();

        for(int i=0;i<5;i++){
    
    
            System.out.println(i+1+"...");
            try {
    
    
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            if(i == 2){
    
    
                t2.interrupt();
            }
        }


    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43935927/article/details/114055404
今日推荐