一、Lock锁接口
定义Java中Java.Util.concurrent 中锁 Lock 的基本接口方法
二、Lock 接口方法
Lock 接口有以下几个方法
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
lock() 是一直等到获取锁
void lock();
tryLock() 是尝试获取锁
boolean tryLock();
tryLock(Long time, TimeUnit time) 设置尝试在某个时间内获取锁,过了这个时间就不尝试获取了
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
lockInterruptibly 中止锁
void lockInterruptibly() throws InterruptedException;
unlock( ) 解锁
unlock();
newCondition 稍后解释
Condition newCondition();
三、lock 使用
Lock的使用,通过实现Lock接口的 ReentranLock 类来实现;
3.1、lock()
import org.apache.tomcat.jni.Time;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo {
static Lock lock = new ReentrantLock();
public static void main(String[] args) throws Exception{
lock.lock();
Thread th = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("========= Try to get lock : " + System.currentTimeMillis());
// lock 会一直等到线程可以拿到锁为止再运行
lock.lock();
System.out.println("========= Get lock : " + System.currentTimeMillis());
}
});
System.out.println("========= Begin : " + System.currentTimeMillis());
th.start();
Thread.sleep(2000);
System.out.println("========= After sleep: " + System.currentTimeMillis());
lock.unlock();
System.out.println("========= End : " + System.currentTimeMillis());
}
}
打印
========= Begin : 1596676916634
========= Try to get lock : 1596676916636
========= After sleep: 1596676918636
========= Get lock : 1596676918637
========= End : 1596676918637
代码演示图

说明:
(1)主线程 A 先获取到锁;
(2)启动另外一个线程 B;
(3)线程 B 尝试获取 锁,获取不到,进入锁池, 等待获取锁,运行跳回主线程A;
(4)线程 A 进入休眠 2 秒;
(5)线程 A 休眠完,解开锁,运行并跳回线程 B;
(6) 线程 B 获取锁;
(7)程序结束
3.2、tryLock()
public class LockDemo {
static Lock lock = new ReentrantLock();
public static void main(String[] args) throws Exception{
lock.lock();
Thread th = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("========= Try to get lock : " + System.currentTimeMillis());
boolean get = lock.tryLock();
//这里将显示失败, 因为主线程没有释放锁,所以这个线程获取不到
System.out.println("========= Get lock : " + get );
System.out.println("======== Get lock Time : " + System.currentTimeMillis());
}
});
System.out.println("========= Begin : " + System.currentTimeMillis());
th.start();
Thread.sleep(2000);
System.out.println("========= After sleep: " + System.currentTimeMillis());
lock.unlock();
System.out.println("========= End : " + System.currentTimeMillis());
}
}
打印
========= Begin : 1596678142300
========= Try to get lock : 1596678142300
========= Get lock : false
======== Get lock Time : 1596678142301
========= After sleep: 1596678144300
========= End : 1596678144300
可以看到,由于这个方法,线程没有进入锁池等待获取锁,只要没有获取到锁就不等待了。
3.3、tryLock(Long time, TimeUnit time)
public class LockDemo {
static Lock lock = new ReentrantLock();
public static void main(String[] args) throws Exception{
lock.lock();
Thread th = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("========= Try to get lock : " + System.currentTimeMillis());
boolean get = false;
// 线程在这里等 3秒, 获取到锁
try {
get = lock.tryLock(3000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("========= Get lock : " + get );
System.out.println("========= Get lock Time : " + System.currentTimeMillis());
}
});
System.out.println("========= Begin : " + System.currentTimeMillis());
th.start();
Thread.sleep(2000);
System.out.println("========= After sleep: " + System.currentTimeMillis());
lock.unlock();
System.out.println("========= End : " + System.currentTimeMillis());
}
}
打印
========= Begin : 1596678402148
========= Try to get lock : 1596678402161
========= After sleep: 1596678404148
========= End : 1596678404148
========= Get lock : true
========= Get lock Time : 1596678404148
3.4 lockInterruptibly( )
线程B 等到 线程B调用 interrupt() 方法就不等了
public class InterrupteLockDemo {
static Lock lock = new ReentrantLock();
public static void main(String[] args) throws Exception{
lock.lock();
Thread th = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("========= Try to get lock : " + System.currentTimeMillis());
try {
/*等待,获取锁,直到线程调用 interrupt(), 就不等了*/
lock.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("========= Get lock Time : " + System.currentTimeMillis());
}
});
System.out.println("========= Begin : " + System.currentTimeMillis());
th.start();
Thread.sleep(2000);
System.out.println("========= After sleep: " + System.currentTimeMillis());
th.interrupt();
Thread.sleep(2000);
System.out.println("========= End : " + System.currentTimeMillis());
}
}
打印
========= Begin : 1596683400461
========= Try to get lock : 1596683400462
========= After sleep: 1596683402477
========= Get lock Time : 1596683402479
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at com.jm.lock.InterrupteLockDemo$1.run(InterrupteLockDemo.java:21)
at java.lang.Thread.run(Thread.java:748)
========= End : 1596683404478
3.5 new Condition
public class newCondition {
static Lock lock = new ReentrantLock();
static private Condition condition = lock.newCondition();
public static void main(String[] args) throws Exception{
Thread th = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
System.out.println("当前线程 获得锁 : " + System.currentTimeMillis());
condition.await();//挂起线程
System.out.println("当前线程 开始执行: " + System.currentTimeMillis());
} catch (InterruptedException e) {
lock.unlock();
e.printStackTrace();
}
System.out.println("========= Get lock Time : " + System.currentTimeMillis());
}
});
System.out.println("========= Begin : " + System.currentTimeMillis());
th.start();
Thread.sleep(2000);
System.out.println("========= After sleep: " + System.currentTimeMillis());
lock.lock();
condition.signal();
lock.unlock();
System.out.println("========= End : " + System.currentTimeMillis());
}
}