tryLock(long time, TimeUnit unit) 的作用在給定等待時長內鎖沒有被另外的線程持有,并且當前線程也沒有被中斷,則獲得該鎖,通過該方法可以實現鎖對象的限時等待。
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(); //定義鎖對象
@Override
public void run() {
try {
if ( lock.tryLock(3, TimeUnit.SECONDS) ){ //獲得鎖返回true
System.out.println(Thread.currentThread().getName() + "獲得鎖,執行耗時任務");
// Thread.sleep(4000); //假設Thread-0線程先持有鎖,完成任務需要4秒鐘,Thread-1線程嘗試獲得鎖,Thread-1線程在3秒內還沒有獲得鎖的話,Thread-1線程會放棄
Thread.sleep(2000); //假設Thread-0線程先持有鎖,完成任務需要2秒鐘,Thread-1線程嘗試獲得鎖,Thread-1線程會一直嘗試,在它約定嘗試的3秒內可以獲得鎖對象
}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()僅在調用時鎖定未被其他線程持有的鎖,如果調用方法時,鎖對象對其他線程持有,則放棄,調用方法嘗試獲得沒,如果該鎖沒有被其他線程占用則返回true表示鎖定成功; 如果鎖被其他線程占用則返回false,不等待。
package com.wkcto.lock.reentrant;
import java.util.concurrent.locks.ReentrantLock;
/**
*tryLock()
* 當鎖對象沒有被其他線程持有的情況下才會獲得該鎖定
*/
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); //模擬執行任務的時長
}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 ){ //偶數先鎖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() + "同時獲得鎖1與鎖2 ----完成任務了");
return; //結束run()方法執行,即當前線程結束
}
} finally {
if (lock2.isHeldByCurrentThread()){
lock2.unlock();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock1.isHeldByCurrentThread()){
lock1.unlock();
}
}
}
}else { //奇數就先鎖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() + "同時獲得鎖1與鎖2 ----完成任務了");
return; //結束run()方法執行,即當前線程結束
}
} 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();
//運行后,使用tryLock()嘗試獲得鎖,不會傻傻的等待,通過循環不停的再次嘗試,如果等待的時間足夠長,線程總是會獲得想要的資源
}
}