java线程中断,interrupt()方法的一些示例

众所周知,java线程实例有个interrupt()方法,它的名字很有诱导性,但它实际上并不能立即中断线程。它只是将线程的中断状态置位为true(这是每一个线程都具有的boolean标志,通过isInterrupted()方法可以查看),而设置之后,线程根据当前的状态进行不同的后续操作。

如果线程的当前状态处于非阻塞状态,那么仅仅是线程的中断标志被修改为true不做其他操作。

如果是wait、sleep以及jion三个方法引起的阻塞,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException(异常抛出后一般就退出了,当然只是抛异常而已,如果在内部catch了该异常,线程一样可以继续执行)。这里需要注意的是哪怕线程一开始不在阻塞状态,即只要线程在进入阻塞之前调用了interrupt()来置位了,线程在进入由sleep、wait、join等引起的阻塞状态时也立即抛异常。

如果是不能被中断的IO,则只是置位而无其他操作,如各种流式IO、socket,interrupt是没有用的,但对于NIO,channel会抛ClosedByInterruptException而中断。

既然interrupt()方法并不能真正结束线程,那用什么方式呢? 最通用的一种方式就是使用共享变量(一般用volatile修饰,以保证可见性),告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量(尤其在冗余操作期间),然后有秩序地中止任务,但如果线程是阻塞状态的,那么就无法检查共享变量从而无法结束,所以interrupt()和共享变量可以一起使用。

如下代码包括了上述各种情况:

package com.thread;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class testInterrupt {

	public static void main(String args[]) throws Exception {
		testNotBlockingThread();
		testBlockingThread();
		testBlockingThread2();
		testReadBlockingThread();
	}
	
	public static void testNotBlockingThread() throws InterruptedException{
		NotBlockingThread notBlockingThread = new NotBlockingThread();
		System.out.println("NotBlockingThread Starting...");
		notBlockingThread.start();
		Thread.sleep(3000);
		System.out.println("Interrupting NotBlockingThread...");
		notBlockingThread.interrupt();// 因为线程是运行状态的,没有阻塞,interrupt只是置位而已,并不能中断线程
		Thread.sleep(3000);
		System.out.println("Asking NotBlockingThread to stop...");
		notBlockingThread.stop = true; // 使用共享变量时最好的结束线程的方法,但问题在于如果线程是阻塞状态的,则无法检查共享变量从而无法结束
		Thread.sleep(3000);
		System.out.println("Main thread stop...");
		// System.exit(0); //stop application
	}
	
	public static void testBlockingThread() throws InterruptedException{
		BlockingThread BlockingThread = new BlockingThread();
		System.out.println("BlockingThread Starting...");
		BlockingThread.start();
		Thread.sleep(3000);
		System.out.println("Interrupting BlockingThread...");
		BlockingThread.interrupt();//因为使用了共享变量的方式,所以光interrupt是不行的,线程并不会退出
		Thread.sleep(3000);
		System.out.println("Asking BlockingThread to stop...");
		BlockingThread.stop = true; 
		BlockingThread.interrupt();//两个结合使用才能让线程迅速退出
		Thread.sleep(3000);
		System.out.println("Main thread stop...");
		// System.exit(0); //stop application
	}
	
	public static void testBlockingThread2() throws InterruptedException{
		BlockingThread2 BlockingThread2 = new BlockingThread2();
		BlockingThread2.start();
		BlockingThread2.interrupt();//哪怕线程一开始不在阻塞状态,但只要置位了,线程进入sleep、wait、join等引起的阻塞状态也立即抛异常退出
	}
	
	public static void testReadBlockingThread() throws InterruptedException{
		ReadBlockingThread readBlockingThread = new ReadBlockingThread();
		readBlockingThread.start();
		readBlockingThread.interrupt();//普通的流io操作不可中断,所以根本不理会interrupt,但是NIO里面的channel会抛ClosedByInterruptException而中断
	}
}

class NotBlockingThread extends Thread{
	public volatile boolean stop = false;
	public void run(){
		while (!stop) {
			System.out.println("Thread is running...");
			long time = System.currentTimeMillis();
			while ((System.currentTimeMillis() - time < 1000)) {// 不阻塞
			}
		}
		System.out.println("Thread exiting under request...");
	}
}

class ReadBlockingThread extends Thread{
	public void run(){
		try {
			FileInputStream inputStream=new FileInputStream(new File("I:\\debug2.log"));
			FileChannel channel=inputStream.getChannel();
			/*byte[] b=new byte[100];
			while (inputStream.read(b)>0) {				
			}*/
			ByteBuffer buffer=ByteBuffer.allocate(100);
			while(channel.read(buffer)>0){
			}
			System.out.println("read done");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


class BlockingThread extends Thread{
	public volatile boolean stop = false;
	public void run(){
		while (!stop) {
			System.out.println("Thread is running...");
			try {
				Thread.sleep(1000);//阻塞
			} catch (InterruptedException e) {
				System.out.println("Thread interrupted...");
				//Do some finishing work
			}
		}
		System.out.println("Thread exiting under request...");
	}
}

class BlockingThread2 extends Thread{
	public void run(){
		System.out.println("Thread is running...");
		long time = System.currentTimeMillis();
		while ((System.currentTimeMillis() - time < 5000)) {// 不阻塞地空转5秒
		}
		try {
			Thread.sleep(5000);//阻塞
		} catch (InterruptedException e) {
			System.out.println("Thread interrupted...");
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值