import java.io.IOException; import java.io.InputStream; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * Created by Administrator on 2017/10/12. */ class SleepBlocked implements Runnable { public void run() { try { TimeUnit.SECONDS.sleep(100); } catch (InterruptedException e) { System.out.print("\nInterruptedException"); } System.out.print("\nExiting SleepBlocked.run()"); } } class IOBlocked implements Runnable { private InputStream in; public IOBlocked(InputStream is) { in = is; } public void run() { try { System.out.print("\nwating for read()"); in.read(); } catch (IOException e) { if (Thread.currentThread().isInterrupted()) { System.out.print("\nInterruppted from blocked I/O"); } else { throw new RuntimeException(e); } } System.out.print("Exiting IOBlocked.run()"); } } class SynchronizedBlocked implements Runnable { public synchronized void f() { while (true)//never releases lock Thread.yield(); } public SynchronizedBlocked() { new Thread() { public void run() { System.out.print("\n构造函数trying to call f()"); f(); System.out.print("\n构造函数exiting trying to call f()"); } }.start(); } public void run() { System.out.print("\nRun() Trying to call f()"); f(); System.out.print("\nExiting SynchronizedBlocked.run()"); } } public class Interrupting { private static ExecutorService exec = Executors.newCachedThreadPool(); static void test(Runnable r) throws InterruptedException { Future<?> f = exec.submit(r); TimeUnit.MICROSECONDS.sleep(100); System.out.print("\nInterrupting " + r.getClass().getName()); f.cancel(true);//Interrupting if running System.out.print("\nInterrupted sent to " + r.getClass().getName()); } public static void main(String[] args) throws Exception { test(new SleepBlocked()); test(new IOBlocked(System.in)); test(new SynchronizedBlocked()); TimeUnit.SECONDS.sleep(3); System.out.print("\nAborting with System.exit(0)"); System.exit(0); } }
运行结果:
Interrupting SleepBlocked
Interrupted sent to SleepBlocked
InterruptedException
Exiting SleepBlocked.run()
wating for read()
Interrupting IOBlocked
Interrupted sent to IOBlocked
构造函数trying to call f()
Run() Trying to call f()
Interrupting SynchronizedBlocked
Interrupted sent to SynchronizedBlocked
Aborting with System.exit(0)
Process finished with exit code 0
分析:
sleep()有一种情况,将使任务从执行状态变为阻塞状态,而有时必须终止将被阻塞的任务。
一个线程处于阻塞状态时,调试器将不会分配给线程任何CPU时间,直到线程重新进入就绪状态,它才有可能重新获取CPU。
一个任务进入阻塞状态,可能有如下原因:
(1)通过调用sleep(milliseconds)使任务进行休眠状态,在这种情况下,任务在指定的时间内不会运行。
(2)你通过调用wait()使线程挂起。直到线程得到了notify()或notify all()消息(或者在JAVA SE5的java.util.concurrent类库中等价的signal()或者signalall()消息),线程才会进入就绪状态。
(3)任务在等待某个输入输出完成
(4)任务试图在某个对象上调用其同步控制方法,但是对象锁不可用,因为另一个任务已经获取了这个锁。
如何主动中止阻塞状态?
从以上三个示例可以看出,中断能够中断对sleep()的调用(或者任何要求抛出InterruptedException的调用)。但是,你不能中断正在试图获取synchronized锁或者试图执行I/O操作的线程。