1. 中断的位置和要处理的资源
在Runnable.run()方法的中间打断它,当打断被阻塞的任务的时候,可能要清理资源。为了返回良好的状态,必须仔细考虑代码的执行路径,并仔细写catch子句以正确清除所有事物。
2.Thread类中的interrupt()方法,
可以用来终止任务,这个方法将设置线程的中断状态。如果一个线程已经被阻塞,或者试图执行一个阻塞的操作,那么设置这个线程的中断中断状态将抛出InterruptedException。
Thread.interrupted()提供了离开run()循环而不抛出异常的第二种方法。
3.调用interrupt()方法
为了调用interrupt()方法,必须持有Thread对象。新的concurrent类库避免使用Thread对象的操作,尽量用Executor,如果在Executor上调用shutdownNow(),那么将发送一个interrupt()调用给它启动的所有线程。这么做的意义:因为完成工程中某个部分或者整个程序时,通常希望同时关闭某个特定Executor的所有任务。
有时候希望只中断某个任务,可以使用Executor调用submit()而不是executor()来启动任务,就可以持有该任务的上下文。submit()将返回一个泛型Future<?>其中有一个未修饰的参数,因为永远都不会在其上调用get(),持有这种Future的关键在于你可以在其上调用cancel(),并因此可以使用它来中断某个特定的任务。如果将true传递给cancel(),那么它将会拥有在该线程上调用interrupt()以停止这个线程的权限。因此cancel()是一种中断由Executor启动的单个线程的方式。
4. 例1
package jiangning;
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;
class SleepBlocked implements Runnable{//sleep
blocked
public void run()
{
try {
TimeUnit. SECONDS.sleep(100);
} catch (InterruptedException
e) {
System. out.println("InterruptedException" );
}
}
}
class IOBlocked implements Runnable{//IO
blocked
private InputStream in ;
public IOBlocked(InputStream
in){
this.in =
in;
}
public void run()
{
try {
System. out.println("wait
for read(): " );
in.read();
} catch (IOException
e) {
if(Thread.currentThread ().interrupted()){
System. out.println("Interrupted
from blocked I/O ");
} else{
throw new RuntimeException(e);
}
}
System. out.println("Exiting
IOBlock.run() " );
}
}
class SynchronizedBlocked implements Runnable{//synchronized
block
public synchronized void f(){
while(true ){
Thread. yield();
}
}
public SynchronizedBlocked(){
new Thread(){
public void run(){
f(); //lock
acquired by this Thread
}
}.start();
}
public void run()
{
System. out.println("try
to call f()" );
f();
System. out.println("Exiting
SynchronizedBlock.run()" );
}
}
public class Interrupteing
{
private static ExecutorService exec =
Executors.newCachedThreadPool();
static void test(Runnable
r ) throws InterruptedException{
Future<?> f = exec.submit(r);
TimeUnit. MILLISECONDS.sleep(100);
System. out.println("Interruping
" + r.getClass().getName());
f.cancel( true);//interrupts
if running
System. out.println("Interrupte
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.println("Aborting
with System.exit(0)" );
System. exit(0);
}
}
/**
Interruping jiangning .SleepBlocked
Interrupte sent to jiangning.SleepBlocked
InterruptedException
wait for read():
Interruping jiangning .IOBlocked
Interrupte sent to jiangning.IOBlocked
try to call f()
Interruping jiangning .SynchronizedBlocked
Interrupte sent to jiangning.SynchronizedBlocked
Aborting with System.exit(0)
*/
5.关闭任务在其上发生阻塞的底层资源:
例2.这个例子没有看明白???
package jiangning;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CloseResource
{
public static void main(String[]
args) throws Exception {
ExecutorService exec = Executors. newCachedThreadPool();
ServerSocket server = new ServerSocket(8080);
InputStream sockedInput = new Socket("localhost" ,8080).getInputStream();
exec.execute( new IOBlocked(sockedInput));
exec.execute( new IOBlocked(System.in));
TimeUnit. MILLISECONDS.sleep(100);
System. out.println("shutdown
all Threads" );
exec.shutdownNow();//关闭所有线程
TimeUnit. SECONDS.sleep(1);
System. out.println("closing
" + sockedInput.getClass().getName());
sockedInput.close();
TimeUnit. SECONDS.sleep(1);
System. out.println("closing
" + System.in.getClass().getName());
System. in.close();
}
}
/**
wait for read():
wait for read():
shutdown all Threads
closing java.net.SocketInputStream
Interrupted from blocked I/O
Exiting IOBlock.run()
closing java. io.BufferedInputStream
*/
分析:一旦底层资源被关闭,任务将解除阻塞。interrupt()看起来发生在关闭Socked而不是关闭System.in的时刻。
6.例子3
package jiangning.c21;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
class NIOBlocked implements Runnable{
private final SocketChannel sc;
public NIOBlocked(SocketChannel
sc){
this.sc =
sc;
}
public void run()
{
try {
System. out.println("waiting
for read() in " + this);
sc.read(ByteBuffer. allocate(1));
} catch (ClosedByInterruptException
e) {
System. out.println("ClosedByInterruptException" );
} catch (AsynchronousCloseException
e){
System. out.println("AsynchronousCloseException" );
} catch (IOException
e){
throw new RuntimeException(e);
}
System. out.println("exiting
NIOBlocked.run()" );
}
}
public class NIOInterruption
{
public static void main(String[]
args) throws Exception {
ExecutorService exec = Executors. newCachedThreadPool();
ServerSocket server = new ServerSocket(8080);
InetSocketAddress isa = new InetSocketAddress("localhost" ,8080);
SocketChannel sc1 = SocketChannel. open(isa);
SocketChannel sc2 = SocketChannel. open(isa);
Future<?> f = exec.submit( new NIOBlocked(sc1));
exec.execute( new NIOBlocked(sc2));
exec.shutdown();
TimeUnit. SECONDS.sleep(1);
f.cancel( true);
TimeUnit. SECONDS.sleep(1);
sc2.close();
}
}
/**
waiting for read() in jiangning.c21.NIOBlocked@b0bad7
waiting for read() in jiangning.c21.NIOBlocked@ba9340
ClosedByInterruptException
exiting NIOBlocked.run()
AsynchronousCloseException
exiting NIOBlocked.run()
*/
没有太看明白???
7.被互斥所阻塞