tryLock(long time, TimeUnit unit) 的作用在給定等待時(shí)長(zhǎng)內(nèi)鎖沒有被另外的線程持有,并且當(dāng)前線程也沒有被中斷,則獲得該鎖,通過該方法可以實(shí)現(xiàn)鎖對(duì)象的限時(shí)等待。
package com.wkcto.lock.reentrant;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
*tryLock(long time, TimeUnit unit) 的基本使用
*/
public class Test07 {
static class TimeLock implements Runnable{
private static ReentrantLock lock = new ReentrantLock(); //定義鎖對(duì)象
@Override
public void run() {
try {
if ( lock.tryLock(3, TimeUnit.SECONDS) ){ //獲得鎖返回true
System.out.println(Thread.currentThread().getName() + "獲得鎖,執(zhí)行耗時(shí)任務(wù)");
// Thread.sleep(4000); //假設(shè)Thread-0線程先持有鎖,完成任務(wù)需要4秒鐘,Thread-1線程嘗試獲得鎖,Thread-1線程在3秒內(nèi)還沒有獲得鎖的話,Thread-1線程會(huì)放棄
Thread.sleep(2000); //假設(shè)Thread-0線程先持有鎖,完成任務(wù)需要2秒鐘,Thread-1線程嘗試獲得鎖,Thread-1線程會(huì)一直嘗試,在它約定嘗試的3秒內(nèi)可以獲得鎖對(duì)象
}else { //沒有獲得鎖
System.out.println(Thread.currentThread().getName() + "沒有獲得鎖");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}
public static void main(String[] args) {
TimeLock timeLock = new TimeLock();
Thread t1 = new Thread(timeLock);
Thread t2 = new Thread(timeLock);
t1.start();
t2.start();
}
}
tryLock()僅在調(diào)用時(shí)鎖定未被其他線程持有的鎖,如果調(diào)用方法時(shí),鎖對(duì)象對(duì)其他線程持有,則放棄,調(diào)用方法嘗試獲得沒,如果該鎖沒有被其他線程占用則返回true表示鎖定成功; 如果鎖被其他線程占用則返回false,不等待。
package com.wkcto.lock.reentrant;
import java.util.concurrent.locks.ReentrantLock;
/**
*tryLock()
* 當(dāng)鎖對(duì)象沒有被其他線程持有的情況下才會(huì)獲得該鎖定
*/
public class Test08 {
static class Service{
private ReentrantLock lock = new ReentrantLock();
public void serviceMethod(){
try {
if (lock.tryLock()){
System.out.println(Thread.currentThread().getName() + "獲得鎖定");
Thread.sleep(3000); //模擬執(zhí)行任務(wù)的時(shí)長(zhǎng)
}else {
System.out.println(Thread.currentThread().getName() + "沒有獲得鎖定");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Service service = new Service();
Runnable r = new Runnable() {
@Override
public void run() {
service.serviceMethod();
}
};
Thread t1 = new Thread(r);
t1.start();
Thread.sleep(50); //睡眠50毫秒,確保t1線程鎖定
Thread t2 = new Thread(r);
t2.start();
}
}
package com.wkcto.lock.reentrant;
import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用tryLock()可以避免死鎖
*/
public class Test09 {
static class IntLock implements Runnable{
private static ReentrantLock lock1 = new ReentrantLock();
private static ReentrantLock lock2 = new ReentrantLock();
private int lockNum; //用于控制鎖的順序
public IntLock(int lockNum) {
this.lockNum = lockNum;
}
@Override
public void run() {
if ( lockNum % 2 == 0 ){ //偶數(shù)先鎖1,再鎖2
while (true){
try {
if (lock1.tryLock()){
System.out.println(Thread.currentThread().getName() + "獲得鎖1, 還想獲得鎖2");
Thread.sleep(new Random().nextInt(100));
try {
if (lock2.tryLock()){
System.out.println(Thread.currentThread().getName() + "同時(shí)獲得鎖1與鎖2 ----完成任務(wù)了");
return; //結(jié)束run()方法執(zhí)行,即當(dāng)前線程結(jié)束
}
} finally {
if (lock2.isHeldByCurrentThread()){
lock2.unlock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock1.isHeldByCurrentThread()){
lock1.unlock();
}
}
}
}else { //奇數(shù)就先鎖2,再鎖1
while (true){
try {
if (lock2.tryLock()){
System.out.println(Thread.currentThread().getName() + "獲得鎖2, 還想獲得鎖1");
Thread.sleep(new Random().nextInt(100));
try {
if (lock1.tryLock()){
System.out.println(Thread.currentThread().getName() + "同時(shí)獲得鎖1與鎖2 ----完成任務(wù)了");
return; //結(jié)束run()方法執(zhí)行,即當(dāng)前線程結(jié)束
}
} finally {
if (lock1.isHeldByCurrentThread()){
lock1.unlock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock2.isHeldByCurrentThread()){
lock2.unlock();
}
}
}
}
}
}
public static void main(String[] args) {
IntLock intLock1 = new IntLock(11);
IntLock intLock2 = new IntLock(22);
Thread t1 = new Thread(intLock1);
Thread t2 = new Thread(intLock2);
t1.start();
t2.start();
//運(yùn)行后,使用tryLock()嘗試獲得鎖,不會(huì)傻傻的等待,通過循環(huán)不停的再次嘗試,如果等待的時(shí)間足夠長(zhǎng),線程總是會(huì)獲得想要的資源
}
}