1.可中断
这个特点具体指的是,在线程尝试获得这个被其他线程拥有的锁的时候,会进入阻塞状态,这个ReentrantLock可以被其他线程打断等待的状态,进而退出阻塞等待的状态。具体使用见如下代码
package org.example.juclearning.learning02;
import java.util.concurrent.locks.ReentrantLock;
public class Ruse {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread() {
@Override
public void run() {
try {
lock.lockInterruptibly();
System.out.println("thread1获得锁了");
} catch (InterruptedException e) {
System.out.println("t1被打断");
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
try {
lock.lockInterruptibly();
System.out.println("thread2 获得锁了");
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println("wwww" + i);
if(i == 5){
thread1.interrupt();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
};
thread2.start();
Thread.sleep( 1);
thread1.start();
}
}
在代码里面的24行,指明获取锁的时候是一个可以被打断的获取方式,在31行,其他线程成功执行了锁的打断。
2.可设置为公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
3.可以设置超时时间
package org.example.juclearning.learning02;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class Ruse02TryLock {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread() {
@Override
public void run() {
try {
if (!lock.tryLock(1, TimeUnit.SECONDS)){
System.out.println("t1在一定时间内没有获得到锁");
return;
}
}catch (InterruptedException e){
e.printStackTrace();
}
try {
System.out.println("t1成功地获得到了锁");
}
finally {
lock.unlock();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
try {
if (!lock.tryLock(3, TimeUnit.SECONDS)) {
System.out.println("t2在一定时间内没有获得到锁");
return;
}
System.out.println("t2成功地获得到了锁");
Thread.sleep(4000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
};
t2.start();
Thread.sleep(1000);
t1.start();
}
}
在11行的代码中,使用lock.tryLock方式获得锁,即表示在一定时间内还没有获得锁就会放弃获取。
4.支持多个条件变量(多个waitSet房间)
public class Rusr03Cond {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
Condition c3 = lock.newCondition();
new Thread(){
@Override
public void run() {
try {
lock.lock();
c1.await();
System.out.println("1");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}.start();
new Thread(){
@Override
public void run() {
try {
lock.lock();
c1.await();
System.out.println("11");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}.start();
new Thread(){
@Override
public void run() {
try {
lock.lock();
c2.await();
System.out.println("2");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}.start();
new Thread(){
@Override
public void run() {
try {
lock.lock();
c2.await();
System.out.println("22");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}.start();
new Thread(){
@Override
public void run() {
try {
lock.lock();
c3.await();
System.out.println("3");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}.start();
new Thread(){
@Override
public void run() {
try {
lock.lock();
c3.await();
System.out.println("33");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}.start();
System.out.println();
lock.lock();
try {
c1.signalAll();
}finally {
lock.unlock();
}
}
}
个人是非常喜欢ReentranLock这个类的这个特点,相当于可以给这个锁设置了多个可以等待的房间,而不像wait方法,所有线程都集中在一个房间中。这样的话可以进行有针对性的唤醒动作,进而可以避免虚假唤醒的情况。