Lock接口几种方法处理机制:
lock(), 拿不到lock就不罢休,不然线程就一直block。 比较无赖的做法。
tryLock(),马上返回,拿到lock就返回true,不然返回false。 比较潇洒的做法。
带时间限制的tryLock(),拿不到lock,就等一段时间,超时返回false。比较聪明的做法。
下面的lockInterruptibly()就稍微难理解一些:
先说说线程的打扰机制,每个线程都有一个 打扰 标志。这里分两种情况,
1. 线程在sleep或wait,join, 此时如果别的进程调用此进程的 interrupt()方法,此线程会被唤醒并被要求处理InterruptedException;(thread在做IO操作时也可能有类似行为)
2. 此线程在运行中, 则不会收到提醒。但是 此线程的 “打扰标志”会被设置, 可以通过isInterrupted()查看并 作出处理。
lockInterruptibly()和上面的第一种情况是一样的, 线程在请求lock并被阻塞时,如果被interrupt,则“此线程会被唤醒并被要求处理InterruptedException”。
测试例:
1.
public static void test1() throws Exception {
final Lock lock = new ReentrantLock();
lock.lock();
Thread.sleep(1000);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
});
t1.start();
Thread.sleep(1000);
t1.interrupt();
Thread.sleep(1000000);
}
运行后不会有任何结果,线程一直处于阻塞状态
2.
public static void test2() throws Exception {
final Lock lock = new ReentrantLock();
lock.lock();
Thread.sleep(1000);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
}
});
t1.start();
Thread.sleep(1000);
t1.interrupt();
Thread.sleep(1000000);
}
运行后,会响应得到:Thread-0 interrupted.
3.
public static void test3() throws Exception {
final Lock lock = new ReentrantLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
lock.lockInterruptibly();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
}
});
t1.start();
t1.interrupt();
Thread.sleep(100000);
}
运行后,得到:Thread-0 interrupted.