-
线程阻塞状态与等待状态(当一个线程处于被阻塞或等待状态时,它暂时不活动,不允许任何代码且消耗最少的资源)
-
当一个线程试图获得一个内部的对象锁(而不是java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入 阻塞状态
-
当一个线程等待另一个线程通知调度器的一个条件时,它自己进入 等待状态。在调用Object.wait方法或Thread.join方法,或者是等待java.util.concurrent库中的Lock或Condition时,就会出现这种情况。 实际上被阻塞状态与等待状态是有很大不同的
-
带有超时参数的方法,调用它们线程会进入 计时等待状态。这一状态将一直保持到超时期满或者接收到适合的通知。带有超时的方法有Thread.sleep、Object.wait、Thread.join、Lock.tryLock、Condition.await
没有强制线程终止的方法。然而Interrupt方法可以用来请求终止线程,当对一个线程调用interrupt方法时,线程的
中断状态被置位,这是每一个线程都有的boolean状态,每个线程应该不是的检查这个标志,以判断线程是否被中断。当一个线程的中断状态被置位时,被中断的线程决定如何响应中断
-
intrrupt方法,用来中断线程
-
interrupted是一个静态方法,它检测当前线程是否被中断。而且, 该方法会清除该线程的中断状态,重置中断状态为false
-
isInterrupted是一个实例方法,检验是否有线程被中断,不会改变中断状态
线程中断时抛出InterruptedException异常解析
-
当一个线程调在sleep方法时,如果在该线程上调用interrupt方法, 将抛出异常
-
当一个线程进入一个同步阻塞( synchronize(o))的等待集wait时,调用interrupt方法, 将抛出异常
-
当线程等待concurrent库中锁Lock时, 被中断不抛异常
-
当线程进入concurrent库中条件等待集await时, 被中断不抛异常
-
如果在中断状态被置位时调用sleep方法,不会休眠, 反而会清除这一状态(!)并抛出InterruptException异常
锁测试与超时
-
tryLock方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false。而且线程可以离开去做其他事情
-
lock方法不能被中断。如果一个线程在等待获得一个锁时被中断,并不会抛出异常。中断线程在获得锁之前一直处于阻塞状态。如果出现死锁,那么,lock方法就无法终止
-
然而,如果调用带有超时参数的tryLock(1000,TimeUnit.MILLISECONDS),那么如果线程在等待期间被中断, 将会抛出InterruptedException异常。这是一个非常有用的特性,因为允许程序打破死锁
-
// 当一个线程调在sleep方法时,如果在该线程上调用interrupt方法
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(1000);
t.interrupt(); // 抛出异常
}
}
// 当一个线程进入一个同步阻塞( synchronize(o))的等待集wait时
public class Demo {
public Object o = new Object();
public void fun() throws InterruptedException {
synchronized (o) {
o.wait();
}
}
public static void main(String[] args) throws InterruptedException {
Demo demo = new Demo();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
demo.fun();
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(1000);
t.interrupt(); // 抛出异常
}
}
// 当线程等待concurrent库中锁Lock时
public class Bank {
private Lock bankLock;
private Condition sufficientFunds;
public Bank() {
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition();
}
public void transfer() throws InterruptedException {
bankLock.lock(); // 线程t2不抛出异常,可能发生同步阻塞,建议使用带超时的tryLock(1000,TimeUnit.MILLISECONDS),调用interrupt时抛出异常
// if (bankLock.tryLock()) // 线程t2获取不到锁,立即离开做其他事情
// if (bankLock.tryLock(3000, TimeUnit.MILLISECONDS)) // 线程t2抛出异常
// {
try {
while (true) {
}
} finally {
bankLock.unlock();
}
// }
}
public static void main(String[] args) throws InterruptedException {
Bank bank = new Bank();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
bank.transfer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
bank.transfer();
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
Thread.sleep(2000);
t2.interrupt();
}
}
// 当线程进入concurrent库中条件等待集await时
public class Bank {
private Lock bankLock;
private Condition sufficientFunds;
public Bank() {
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition();
}
public void transfer(boolean b,boolean c) throws InterruptedException {
bankLock.lock();
try {
if (b)
sufficientFunds.await();
while (c) {
}
sufficientFunds.signalAll();
} finally {
bankLock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
Bank bank = new Bank();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
bank.transfer(true,false);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
bank.transfer(false,true);
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
Thread.sleep(2000);
t1.interrupt();
}
}