文章目录
什么是 Lock?
Lock 的中文意思指的是锁,Lock 是 java.util.concurrent.locks 包下的一个接口,该接口作用于线程同步机制,类似同步块。新的锁定机制更加灵活,提供比同步块更多的选项。
锁和同步块之间的区别?
锁和同步块之间的主要区别如下:
- 序列的保证:同步块不提供对等待线程进行访问的序列的任何保证,但 Lock 接口处理它
- 无超时:如果未授予锁,则同步块没有超时选项,但 Lock 接口提供了这样的选项
- 单一方法:同步块必须完全包含在单个方法中,而 Lock 接口的方法 lock() 和 unLock() 可以以不同的方式调用
Lock 的定义
Lock 的定义如下:
public interface Lock
Lock 中的方法
lock()
获取锁
如果该锁不可用,则出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到获得该锁为止
void lock()
lockInterruptibly()
说明:
- 除非当前线程被中断,否则获取锁。
- 获取锁(如果有)并立即返回。
- 如果该锁不可用,则出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到发生以下两种情况之一:
- 该锁由当前线程获取; 要么
其他一些线程中断当前线程,并支持锁定获取的中断。如果当前线程: - 在进入此方法时已设置其中断状态; 要么
获取锁时被中断,并且支持锁获取的中断,
然后抛出InterruptedException并清除当前线程的中断状态。
- 该锁由当前线程获取; 要么
void lockInterruptibly() throws InterruptedException
tryLock()
仅在调用时释放锁时才获取锁
获取锁(如果有),并立即返回true值
如果锁不可用,则此方法将立即返回false值
boolean tryLock()
tryLock(long time,TimeUnit unit)
如果在给定的等待时间内没有锁,并且当前线程尚未中断,则获取锁。
如果锁可用,则此方法立即返回true值。如果该锁不可用,则出于线程调度目的,当前线程将被禁用,并在发生以下三种情况之一之前处于休眠状态:
- 该锁由当前线程获取;要么
- 其他一些线程会中断当前线程,并支持中断获取锁;要么
- 经过指定的等待时间
如果获得了锁,则返回值true。
如果当前线程:
- 在进入此方法时已设置其中断状态;要么
- 在获取锁时被中断,并且支持锁获取的中断,
然后抛出InterruptedException并清除当前线程的中断状态。
如果经过了指定的等待时间,则返回值false。如果时间小于或等于零,则该方法将根本不等待。
boolean tryLock(long time,TimeUnit unit) throws InterruptedException
unlock()
释放锁
void unlock()
举例:(Lock 的使用)
以下 TestThread 程序演示了使用 Lock 接口的一些方法。 这里我们使用 lock() 获取锁和 unlock() 来释放锁
package com.java.springtest.testdemo;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author Woo_home
* @create by 2020/2/2
*/
public class TestThread {
public static void main(String[] args) {
PrintThread printThread = new PrintThread();
ThreadDemo threadDemo1 = new ThreadDemo("Thread - 1 ",printThread);
ThreadDemo threadDemo2 = new ThreadDemo("Thread - 2 ",printThread);
ThreadDemo threadDemo3 = new ThreadDemo("Thread - 3 ",printThread);
ThreadDemo threadDemo4 = new ThreadDemo("Thread - 4 ",printThread);
ThreadDemo threadDemo5 = new ThreadDemo("Thread - 5 ",printThread);
threadDemo1.start();
threadDemo2.start();
threadDemo3.start();
threadDemo4.start();
threadDemo5.start();
}
}
class PrintThread {
private final Lock queueLock = new ReentrantLock();
public void printMessage() {
// 加锁
queueLock.lock();
try {
Long duration = (long) (Math.random() * 10000);
System.out.println(Thread.currentThread().getName() + " Time Taken " + (duration / 1000) + " seconds");
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.printf("%s printed the successfully.\n",Thread.currentThread().getName());
// 释放锁
queueLock.unlock();
}
}
}
class ThreadDemo extends Thread {
private PrintThread printThread;
public ThreadDemo(String name, PrintThread printThread) {
super(name);
this.printThread = printThread;
}
@Override
public void run() {
System.out.printf("%s starts printing a document\n",Thread.currentThread().getName());
printThread.printMessage();
}
}
输出: