一、Lock接口中定义的方法
Lock接口中定义的方法
序号 | 方法签名 | 描述 |
1 | void lock(); | 获取锁(就一直等,直到拿到锁) |
2 | boolean tryLock(); | 获取锁(只尝试一次,拿不到就放弃) |
3 | boolean tryLock(long time, TimeUnit unit) throws InterruptedException; | 获取锁(在给定的时间内等待,超时就放弃) |
4 | void lockInterruptibly() throws InterruptedException; | 获取锁(通常情况下不会放弃,但如果外部有一个线程或方法将获取锁的方法中断,就不在获取锁了) |
5 | void unlock(); | 释放锁 |
6 | Condition 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实现类可能没有实现此方法。
感兴趣的可以复制代码到编译器中运行来查看结果,欢迎交流指定。