JAVA JUC 之 Lock接口及其实现(上)

5 篇文章 0 订阅
3 篇文章 0 订阅

一、Lock接口中定义的方法

Lock接口中定义的方法

序号

方法签名

描述

1void lock();获取锁(就一直等,直到拿到锁)
2boolean tryLock();获取锁(只尝试一次,拿不到就放弃)
3boolean tryLock(long time, TimeUnit unit) throws InterruptedException;获取锁(在给定的时间内等待,超时就放弃)
4void lockInterruptibly() throws InterruptedException;获取锁(通常情况下不会放弃,但如果外部有一个线程或方法将获取锁的方法中断,就不在获取锁了)
5void unlock();释放锁
6Condition newContition(); 

在这里我先和大家分享一下前4个方法的使用,第5个unlock就是释放锁,不用多说,第6个newContition我会放到下一篇博客中和大家分享。

二、代码示例:

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

/**
 * @author tongke
 * @email tongkp@126.com
 * @create 2020-07-23 22:29
 */
public class GetLock_Demo {
    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        GetLock_Demo lockDemo = new GetLock_Demo();
        lockDemo.lock();
//        lockDemo.tryLock();
//        lockDemo.tryLockByTime();
//        lockDemo.lockInterruptibly();
    }

    /**
     * 一直等,直到拿到锁
     * 此示例中子线程会等到主线程释放锁,然后拿到锁
     * @throws InterruptedException
     */
    private void lock() throws InterruptedException {
        lock.lock();    //此时主线程一定能拿到锁
        Thread th = new Thread(new Runnable() {     //开启一个子线程来抢锁
            public void run() {
                System.out.println("尝试获取锁");
                lock.lock();    //在超时时间范围内等待,超时仍未拿到就放弃
                System.out.println("获取到锁了");
            }
        });
        th.start();
        Thread.sleep(2000L);
        th.interrupt();
        System.out.println("th 线程被中断了");
        Thread.sleep(5000);
        lock.unlock();
        System.out.println("锁被释放");
    }

    /**
     * 在超时时间范围内等待,超时仍未拿到就放弃
     * 此示例中子线程拿不到锁,因为主线程延迟了1秒才释放锁,此处,如果想让子线程拿到锁可以去掉Thread.sleep(1000)或者在获取锁之前等待1秒
     * @throws InterruptedException
     */
    private void tryLock() throws InterruptedException {
        lock.lock();    //此时主线程一定能拿到锁
        Thread th = new Thread(new Runnable() {     //开启一个子线程来抢锁
            public void run() {
                System.out.println("尝试获取锁");
                boolean tryLock = lock.tryLock();    //在超时时间范围内等待,超时仍未拿到就放弃
                System.out.println("是否获取到锁:"+tryLock);
            }
        });
        th.start();
        Thread.sleep(1000);
        lock.unlock();
    }

    /**
     * 在超时时间范围内等待,超时仍未拿到就放弃
     * 此示例中由主线程先拿到锁,然后开启一个子线程去抢锁,由于子线程中的tryLock只等了2秒,此时主线程还没有释放锁,
     * 所以此处的子线程无法拿到锁,若想让子线程拿到锁,可以将tryLock的等待时间稍长一点,或者让主线程早一点释放锁
     * @throws InterruptedException
     */
    private void tryLockByTime() throws InterruptedException {
        lock.lock();    //主线程一定能拿到锁
        Thread th = new Thread(new Runnable() {     //开启一个子线程来抢锁
            public void run() {
                boolean tryLock = false;
                try {
                    System.out.println("尝试获取锁");
                    tryLock = lock.tryLock(2, TimeUnit.SECONDS);    //在超时时间范围内等待,超时仍未拿到就放弃
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("是否获取到锁:"+tryLock);
            }
        });
        th.start();
        Thread.sleep(2000L);
        lock.unlock();
        //注意了,上面的代码中,主线程拿到锁之后休眠了2秒钟才释放锁,而我们子线程中的tryLock只等待了1秒,所以此处子线程肯定是拿不到锁的,如果想让子线程中的tryLock拿到锁,要么让主线程早一点释放锁,要么要子线程多等一会儿。
    }

    /**
     * 一直等,等到主线程被中断就放弃拿锁,如果在主线程中断之前释放了锁,子线程中的lockInterruptibly就可以拿到锁
     * 此示例中子线程拿不到锁,因为在锁被释放之前主线程已经被中断了
     * @throws InterruptedException
     */
    private void lockInterruptibly() throws InterruptedException {
        lock.lock();    //此时主线程一定能拿到锁
        Thread th = new Thread(new Runnable() {     //开启一个子线程来抢锁
            public void run() {
                try {
                    System.out.println("尝试获取锁");
                    lock.lockInterruptibly();    //
                    System.out.println("获取到锁了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        th.start();
        Thread.sleep(2000L);
        th.interrupt();
        System.out.println("th 线程被中断了");
        Thread.sleep(5000);
        lock.unlock();
        System.out.println("释放锁");
    }

}

三、总结

1、lock()最常用。

2、lockInterruptibly()较少用,有的Lock实现类可能没有实现此方法。

 

感兴趣的可以复制代码到编译器中运行来查看结果,欢迎交流指定。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值