1. lock():获取锁,如果锁不可用,则当前线程将被禁用以进行线程调度,并处于休眠状态,直到获取锁。
package com.zsx.demo.lock;
import lombok.extern.log4j.Log4j2;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Log4j2
public class LockMethodLock {
private final Lock lock = new ReentrantLock();
public void printLock() {
try {
lock.lock();
log.info("Current thread {} get lock, enters the printLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
log.info("Current thread {} unlock, exits the printLock method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
lock.unlock();
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
LockMethodLock lockDemo = new LockMethodLock();
new Thread(() -> {
lockDemo.printLock();
}, String.format("A-t%d", i)).start();
}
}
}
1.运行结果
18:16:36.694 [A-t1] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t1 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t0] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t0 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t4] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t4 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t3] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t3 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:36.694 [A-t2] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t2 get lock, enters the printLock method, enter current time : 2019-12-05T18:16:36.687915900
18:16:38.701 [A-t3] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t3 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t1] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t1 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t4] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t4 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t2] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t2 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
18:16:38.701 [A-t0] INFO com.zsx.demo.lock.LockMethodLock - Current thread A-t0 unlock, exits the printLock method, exit current time : 2019-12-05T18:16:38.701869900
2.tryLock():如果获取成功,则返回true,如果获取失败,则返回false
tryLock(long time, TimeUnit unit):如果一开始拿到锁或者在等待期间内拿到了锁,返回true,否则返回false
package com.zsx.demo.lock;
import lombok.extern.log4j.Log4j2;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Log4j2
public class LockMethodPrintTryLock {
private final Lock lock = new ReentrantLock();
public void printTryLock() {
if (lock.tryLock()) {
try {
log.info("Current thread {} get lock, enters the printTryLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
log.info("Current thread {} unlock, exits the printTryLock method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
lock.unlock();
}
} else {
log.info("Failed to acquire lock on current thread {}, enters the printTryLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
}
}
public void printTryLockLong(long time) {
try {
if (lock.tryLock(time, TimeUnit.SECONDS)) {
try {
log.info("Current thread {} get lock, enters the printTryLockLong method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
TimeUnit.SECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
log.info("Current thread {} unlock, exits the printTryLockLong method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
lock.unlock();
}
} else {
log.info("Failed to acquire lock on current thread {}, enters the printTryLock method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
}
} catch (InterruptedException e) {
log.info("The current thread {} is interrupted", Thread.currentThread().getName());
}
}
public static void main(String[] args) {
LockMethodPrintTryLock lock = new LockMethodPrintTryLock();
new Thread(() -> {
lock.printTryLock();
}, "t1").start();
try {
// 让t1先执行
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
// 由于t1中间停顿4秒, t2在规定时间内拿不到锁
lock.printTryLockLong(2);
}, "t2").start();
try {
// 确保t1、t2执行完,释放锁,不影响后续操作
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
lock.printTryLockLong(5);
}, "t3").start();
try {
// 让t3先执行
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
// t3没有释放锁,t4拿不到锁
lock.printTryLock();
}, "t4").start();
}
}
2.运行结果
16:52:35.073 [t1] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t1 get lock, enters the printTryLock method, enter current time : 2019-12-05T16:52:35.067740200
16:52:37.362 [t2] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Failed to acquire lock on current thread t2, enters the printTryLock method, enter current time : 2019-12-05T16:52:37.362847500
16:52:39.077 [t1] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t1 unlock, exits the printTryLock method, exit current time : 2019-12-05T16:52:39.077296900
16:52:41.364 [t3] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t3 get lock, enters the printTryLockLong method, enter current time : 2019-12-05T16:52:41.364905500
16:52:41.665 [t4] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Failed to acquire lock on current thread t4, enters the printTryLock method, enter current time : 2019-12-05T16:52:41.665123700
16:52:46.365 [t3] INFO com.zsx.demo.lock.LockMethodPrintTryLock - Current thread t3 unlock, exits the printTryLockLong method, exit current time : 2019-12-05T16:52:46.365824600
3.lockInterruptibly()方法:当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态
package com.zsx.demo.lock;
import lombok.extern.log4j.Log4j2;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Log4j2
public class LockMethodLockInterruptibly {
private final Lock lock = new ReentrantLock();
public void printLockInterruptibly() throws InterruptedException {
lock.lockInterruptibly();
try {
log.info("Current thread {} get lock, enters the printLockInterruptibly method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
while(true) {
}
} finally {
log.info("Current thread {} unlock, exits the printLockInterruptibly method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
lock.unlock();
}
}
public static void main(String[] args) {
LockMethodLockInterruptibly lock = new LockMethodLockInterruptibly();
Thread t1 = new Thread(() -> {
try {
lock.printLockInterruptibly();
} catch (InterruptedException e) {
log.info("The current thread {} is interrupted", Thread.currentThread().getName());
}
}, "t1");
// t1获得锁
t1.start();
try {
// 为了保证t1先行t2运行,睡眠2秒
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread t2 = new Thread(() -> {
try {
lock.printLockInterruptibly();
} catch (InterruptedException e) {
log.info("The current thread {} is interrupted", Thread.currentThread().getName());
}
}, "t2");
// t2启动,尝试获取锁,由于t1一直持有该锁,t2进入等待状态
t2.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 由于t1正在运行,无法中断
t1.interrupt();
// 等待2秒后中断t2
t2.interrupt();
}
}
3.运行结果
16:24:23.819 [t1] INFO com.zsx.demo.lock.LockMethodLockInterruptibly - Current thread t1 get lock, enters the printLockInterruptibly method, enter current time : 2019-12-05T16:24:23.814503400
16:24:27.810 [t2] INFO com.zsx.demo.lock.LockMethodLockInterruptibly - The current thread t2 is interrupted
4. newCondition():.通过Condition能够更加精准地控制多线程的休眠与唤醒。
package com.zsx.demo.lock;
import lombok.extern.log4j.Log4j2;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Log4j2
public class LockMethodNewCondition {
private final Lock lock = new ReentrantLock();
private volatile static int i = 1;
public final Condition conditionA = lock.newCondition();
public final Condition conditionB = lock.newCondition();
public final Condition conditionC = lock.newCondition();
public void printNewCondition(Condition awaitCondition, Condition signalCondition) {
try {
lock.lock();
log.info("Current thread {} get lock, enters the printNewCondition method, enter current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
TimeUnit.SECONDS.sleep(2);
if (i < 3) {
log.info("i: {}", i);
i++;
// 让线程进入等待状态
awaitCondition.await();
// 唤醒指定的线程
signalCondition.signal();
} else {
signalCondition.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
log.info("Current thread {} unlock, exits the printNewCondition method, exit current time : {}", Thread.currentThread().getName(), LocalDateTime.now());
lock.unlock();
}
}
public static void main(String[] args) {
LockMethodNewCondition lock1 = new LockMethodNewCondition();
new Thread(() -> {
lock1.printNewCondition(lock1.conditionA, lock1.conditionB);
}, "A").start();
new Thread(() -> {
lock1.printNewCondition(lock1.conditionB, lock1.conditionC);
}, "B").start();
new Thread(() -> {
lock1.printNewCondition(lock1.conditionC, lock1.conditionA);
}, "C").start();
}
}
4.运行结果
20:15:54.112 [A] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread A get lock, enters the printNewCondition method, enter current time : 2019-12-05T20:15:54.097225200
20:15:56.128 [A] INFO com.zsx.demo.lock.LockMethodNewCondition - i: 1
20:15:56.128 [B] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread B get lock, enters the printNewCondition method, enter current time : 2019-12-05T20:15:56.128307900
20:15:58.143 [B] INFO com.zsx.demo.lock.LockMethodNewCondition - i: 2
20:15:58.143 [C] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread C get lock, enters the printNewCondition method, enter current time : 2019-12-05T20:15:58.143450800
20:16:00.158 [C] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread C unlock, exits the printNewCondition method, exit current time : 2019-12-05T20:16:00.158601600
20:16:00.158 [A] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread A unlock, exits the printNewCondition method, exit current time : 2019-12-05T20:16:00.158601600
20:16:00.158 [B] INFO com.zsx.demo.lock.LockMethodNewCondition - Current thread B unlock, exits the printNewCondition method, exit current time : 2019-12-05T20:16:00.158601600