- Interrupt設置一個線程爲中斷狀態
- Interrupt操作的線程處於sleep,wait,join 阻塞等狀態的時候,會拋出一個InterruptedException
- Interrupt操作的線程在可中斷通道上因調用某個阻塞的 I/O 操作(serverSocketChannel. accept()、socketChannel.connect、socketChannel.open、
socketChannel.read、socketChannel.write、fileChannel.read、fileChannel.write),會拋出一個ClosedByInterruptException - 我們通過try/catch捕獲後則可進行return/break/throw new XXException()等方式返回來銷燬或結束線程
/**
* 常規interrupt
*
* @author Allen
* @date 2017年2月21日
*
*/
public class e1 implements Runnable {
public static void main(String[] args) {
e1 nm=new e1();
Thread thread = new Thread(nm);
System.out.println("躁起來修電腦去");
System.out.println("interrupt state = " + thread.isInterrupted());
thread.start();
nm.sleep(500);
thread.interrupt();
System.out.println("別修復了,世界末日了");
System.out.println("interrupt state = " + thread.isInterrupted());
}
public void run() {
System.out.println("開始修復電腦");
for (int i = 10; i <= 100; i += 10) {
if(Thread.interrupted())
System.out.println("~~別煩我我得修完了");
System.out.println("修復進度" + i + "%");
sleep(200);
}
System.out.println("修復完畢");
}
/**
* 自己寫個sleep條件循環爲了禁止Interrupt對Thread.sleep(x)時的異常拋出
* @param step
* @author Allen
* @date 2017年2月21日
*/
private void sleep(int step) {
long time = System.currentTimeMillis();
while ((System.currentTimeMillis() - time < step)) {
}
}
}
interrupt state = false
開始修復電腦
修復進度10%
修復進度20%
修復進度30%
別修復了,世界末日了
interrupt state = true
~~別煩我我得修完了
修復進度40%
修復進度50%
修復進度60%
修復進度70%
修復進度80%
修復進度90%
修復進度100%
修復完畢
/**
* interrupt try/catch銷燬版
*
* @author Allen
* @date 2017年2月21日
*
*/
public class e2 implements Runnable {
public static void main(String[] args) throws Exception {
e2 nm = new e2();
Thread thread = new Thread(nm);
System.out.println("躁起來修電腦去");
System.out.println("interrupt state = " + thread.isInterrupted());
thread.start();
Thread.sleep(500);
thread.interrupt();
System.out.println("別修復了,世界末日了");
/**
* 因爲Thread.sleep 觸發了中斷狀態 所以interrupted狀態被清除
* 所以這裏打印的也是false
*/
System.out.println("interrupt state = " + thread.isInterrupted());
}
public void run() {
System.out.println("開始修復電腦");
for (int i = 10; i <= 100; i += 10) {
if (Thread.interrupted())
System.out.println("~~別煩我我得修完了");
System.out.println("修復進度" + i + "%");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("拋異常了被try/catch死神捕獲了,只能return了");
return;
}
}
System.out.println("修復完畢");
}
}
輸出
躁起來修電腦去
interrupt state = false
開始修復電腦
修復進度10%
修復進度20%
修復進度30%
別修復了,世界末日了
interrupt state = false //這裏爲什麼返回false了呢?
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at TwoPhaseTerminationPattern.interrupt.e2.run(e2.java:34)
at java.lang.Thread.run(Thread.java:724)
拋異常了被try/catch死神捕獲了,只能return了
可見例子2中因爲是用了Thread.sleep,我們在調用interrupt的時候成功的在目標線程中拋出了InterruptedException,從而我們可以進行一些列操作
Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method.
A thread interruption ignored because a thread was not alive at the time of the interrupt will be reflected by this method returning false.
Returns:
true if this thread has been interrupted; false otherwise.
See Also:
interrupted()
/**
* interrupt i/o阻塞
*
* @author Allen
* @date 2017年2月21日
*
*/
public class e3 implements Runnable {
public static void main(String[] args) throws Exception {
e3 nm = new e3();
Thread thread = new Thread(nm);
System.out.println("燥起來修電腦去");
System.out.println("interrupt state = " + thread.isInterrupted());
thread.start();
Thread.sleep(800);
thread.interrupt();
System.out.println("別修復了,世界末日了");
System.out.println("interrupt state = " + thread.isInterrupted());
}
public void run() {
System.out.println("開始修復電腦");
for (int i = 10; i <= 100; i += 10) {
if (Thread.interrupted())
System.out.println("~~別煩我我得修完了");
System.out.println("修復進度" + i + "%");
if (i == 70) {
try {
System.out.println("建立一個nio ServerSocketChannel我就繼續修復");
ServerSocketChannel ss = ServerSocketChannel.open();
ss.socket().bind(new InetSocketAddress(4488));
System.out.println("建立好了");
while (true) {
// 阻塞一下
ss.accept();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("拋異常了被try/catch死神補貨了,只能return了");
return;
}
}
}
System.out.println("修復完畢");
}
}
輸出
燥起來修電腦去
interrupt state = false
開始修復電腦
修復進度10%
修復進度20%
修復進度30%
修復進度40%
修復進度50%
修復進度60%
修復進度70%
建立一個nio ServerSocketChannel我就繼續修復
建立好了
別修復了,世界末日了
interrupt state = true //這裏怎麼又出現true了,捕獲了exception不是應該重置狀態麼?
java.nio.channels.ClosedByInterruptException
at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:248)
at TwoPhaseTerminationPattern.interrupt.e3.run(e3.java:41)
at java.lang.Thread.run(Thread.java:724)
拋異常了被try/catch死神補貨了,只能return了
public void interrupt()
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared
and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
Interrupting a thread that is not alive need not have any effect.
Throws:
SecurityException - if the current thread cannot modify this thread
中斷線程。
如果當前線程沒有中斷它自己(這在任何情況下都是允許的),則該線程的 checkAccess 方法就會被調用,這可能拋出 SecurityException。
如果線程在調用 Object 類的 wait()、wait(long) 或 wait(long, int) 方法,或者該類的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法過程中受阻,則其中斷狀態將被清除,它還將收到一個 InterruptedException。
如果該線程在可中斷的通道上的 I/O 操作中受阻,則該通道將被關閉,該線程的中斷狀態將被設置並且該線程將收到一個 ClosedByInterruptException。
如果該線程在一個 Selector 中受阻,則該線程的中斷狀態將被設置,它將立即從選擇操作返回,並可能帶有一個非零值,就好像調用了選擇器的 wakeup 方法一樣。
如果以前的條件都沒有保存,則該線程的中斷狀態將被設置。
中斷一個不處於活動狀態的線程不需要任何作用。
拋出:
SecurityException - 如果當前線程無法修改該線程