您的位置:首页 > 编程语言 > Java开发

Java多线程——中断

2016-04-08 10:56 435 查看
中断相关的方法Interrupt isInterrupt interrupted

进行中断

中断阻塞

中断相关的方法(Interrupt, isInterrupt, interrupted)

成员方法isInterrupt()

作用:检测中断标志,并不会清空。返回是否中断,中断为true,未中断为false

public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);


静态方法interrupted()

作用:检测中断标志,并清空中断标志。返回是否中断,中断为true,未中断为false

public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
private native boolean isInterrupted(boolean ClearInterrupted);


进行中断

通过让线程抛出异常中断线程

使用thread.interrupt()方法 。使线程在可中断阻塞中抛出InterruptException()

关闭相应的资源。使得IO阻塞抛出相应的IOException()

循环检测中断标志

使用thread.interrupt()设置中断标志,并且在循环中使用thread.isInterrupted()或者Thread.interrupted()方法检查中断标志

使用自定义标记(flag)来控制是否中断,需要在循环中判断(flag)

中断阻塞

可中断的线程阻塞

如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的

join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int)

方法过程中受阻,则其isInterrupt状态将被清除,设成false, 它还将收到一个InterruptedException.

public void run() {

while (true) {
try{
Thread.sleep(1000);
} catch (InterruptedException ie){
ie.printStackTrace();
return;
}
}
}


如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的isInterrupt状态将被设置成true, 并且该线程将收到一个ClosedByInterruptException。

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() " + this);
}
}
public class NIOInterruption{
public static void main(String[] args) throws IOException, InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
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));  //sc1,sc2相互等待对方发送信息,进入阻塞死循环
exec.shutdown();

TimeUnit.SECONDS.sleep(1);
f.cancel(true);  //中止任务,中断阻塞

TimeUnit.SECONDS.sleep(1);
sc2.close();  //关闭资源,中断阻塞
}
}


等待锁释放,而被阻塞。使用ReentrantLock,可以时锁被中断

与前面在不可中断的I/O中所看到的一样,无论在任何时刻,只要任务以不可中断的方式被阻塞,那么都有潜在的会锁住程序的可能。Java SE5并发类库中添加了一个特性,即在ReentrantLock上阻塞的任务具备可以被中断的能力:.

class BlockedMutex{
private Lock lock = new ReentrantLock();
public BlockedMutex() {
// 构造函数 立刻加锁
lock.lock();
}

public void f() {
try{
//此处将永远无法执行到
lock.lockInterruptibly();
System.out.println("lock acquired in f()");
} catch(InterruptedException e) {
System.out.println("Interrupted from lock acquisition in f()");
}
}
}

class Blocked2 implements Runnable {
BlockedMutex blocked = new BlockedMutex();  //构造出BlockedMutex
public void run() {
System.out.println("Waiting for f() in BlockedMutex");
blocked.f();
System.out.println("Broken out of blocked call");
}
}

public class Interrupting2 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Blocked2());
t.start();

TimeUnit.SECONDS.sleep(1);
System.out.println("Issuing t.interrupt()");
t.interrupt();  //中断阻塞
}
}


不可中断的线程阻塞(无法通过interrupt中断)

等待锁释放,而被阻塞

一般的锁都是不可以中断的,所以在需要中断的线程中应该使用Reentrantlock

class SynchronizedBlocked implements Runnable {
public synchronized void f() {
while(true) {
Thread.yield(); //方法f加锁后不再释放锁
}
}
public SynchronizedBlocked() {
new Thread() {
public void run(){
f();    // 这个类构造时f就加锁了,进入阻塞状态
}
}.start();
}
public void run(){
System.out.println("Trying to call f()    ");
f();  //没有机会执行
System.out.println("Exiting SynchronizedBlocked.run()");
}
}


使用了不可中断的I/O

虽然不可以通过interrupt方法中断,但是可以通过关闭相应的资源,使线程抛出相应的IO异常,从而可以中断线程

class IOBlocked implements Runnable {
private InputStream in;
public IOBlocked(InputStream is){
in = is;
}
public void run(){
try{
System.out.println("Waiting for read();");
in.read();  //调用read方法,进入IO阻塞
} catch(IOException e) {
if(Thread.currentThread().isInterrupted()) {
System.err.println("Interrupted from blocked I/O");
} else {
throw new RuntimeException(e);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: