线程进入阻塞状态,可能有如下原因:
(1)sleep();
(2)wait();
(3)等待某个输入/输出完成
(4)试图在某个对象上调用其同步控制方法,但是对象锁不可用。
(5)调用其他对象的join()
其中(3),(4)不可通过interrupt()中断。
(1)用interrupt()终止由于调用sleep()阻塞的线程。
class Base implements Runnable{
public void run(){
try{
Thread.sleep(1000);
} catch(InterruptedException e ){
System.out.println("interruptedException");
}
}
}
public class Test{
public static void main(String[] args){
Thread t = new Thread(new Base());
t.start();
t.interrupt();
}
}
(2)用interrupt()终止由于调用wait()阻塞的线程。
class Base implements Runnable{
public void run(){
Print();
}
public synchronized void Print(){
System.out.println("hello");
try{
wait();
} catch(InterruptedException e ){
System.out.println("Interrupted Exception");
}
}
}
public class Test{
public static void main(String[] args){
Thread t = new Thread(new Base());
t.start();
t.interrupt();
}
}
sleep(),yield()不会释放对象上的锁,而调用wait()时线程的执行被挂起,对象上的锁被释放。 调用wait()notify()notifyAll()的任务在调用这些方法前必须“拥有”(获取)对象的锁。 因此上例中Print()没有加锁操作,即没有synchronized关键字,则会抛异常:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at Base.Print(Test.java:8)
at Base.run(Test.java:3)
at java.lang.Thread.run(Thread.java:662)
(5)用interrupt()终止由于join()另一个对象阻塞的线程。
class Sleeper extends Thread {
private int duration;
private volatile double d;
public Sleeper(String name, int sleepTime) {
super(name);
duration = sleepTime;
start();
}
public void run() {
for(int i=0; i<10000000; i++){
d += (Math.PI+Math.E)/(double)i;
}
try{
sleep(duration);
} catch(InterruptedException e ){
System.out.println(getName() + " was interrupted. " +
"isInterrupted(): " + isInterrupted());
return;
}
System.out.println(getName() + " has awakened");
}
}
class Joiner extends Thread {
private Sleeper sleeper;
public Joiner(String name, Sleeper sleeper) {
super(name);
this.sleeper = sleeper;
start();
}
public void run() {
try {
sleeper.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println(getName() + " join completed");
}
}
public class Test {
public static void main(String[] args) {
Sleeper sleepy = new Sleeper("Sleepy", 1500);
Joiner dopey = new Joiner("Dopey", sleepy);
dopey.interrupt();
}
}