通常我们会在线程中使用一个标志变量来控制线程的运行,如:
public class TestCallable implements Runnable {
private boolean running = true;
public void stop() {
this.running = false;
}
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (running) {
System.out.println("线程正在运行中...");
Thread.sleep(20000);
}
System.out.println("线程被终止.");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
TestCallable callable = new TestCallable();
Thread th = new Thread(callable);
th.start();
Thread.sleep(1000);
callable.stop();
System.out.println("已下达终止线程命令。");
} catch (Exception e) {
e.printStackTrace();
}
}
}执行上述代码就能发现,线程阻塞在reader.readLine()时,即使主线程改变了标志变量,但是并不能立即结束子线程,只有等待阻塞被打破,且运行到下一次循环条件判断的时候才能终止。所以在使用这种方法时,应该考虑到阻塞这种情况。当然,如果整个循环内的操作属于同一事务时,这种方法倒很不错。
public class TestCallable extends Thread {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
public void stopThread() {
interrupt();
}
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
reader.close();
while (!isInterrupted()) {
System.out.println("线程正在运行中...");
Thread.sleep(20000);
}
System.out.println("线程被终止.");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
TestCallable cal = new TestCallable();
cal.start();
Thread.sleep(2000);
cal.stopThread();
System.out.println("已下达终止线程命令。");
} catch (Exception e) {
e.printStackTrace();
}
}
}调用线程对象的interrupt()时,sleep的线程会抛出InterruptedException异常,从而中断循环,终止线程。public class TestCallable {
public static void main(String[] args) {
// 测试无阻塞的情况,进行中断
Thread thread1 = new Thread(){
public void run(){
try {
long time = System.currentTimeMillis();
while(System.currentTimeMillis()-time<5000){
}
System.out.println("A1");
} catch(Exception e) {
System.out.println("B1");
System.out.println("B1 : " + e.toString());
}
}
};
thread1.start();
thread1.interrupt();
//在线程sleep状态下进行中断
Thread thread2 = new Thread(){
public void run(){
try {
this.sleep(5000);
System.out.println("A2");
} catch (Exception e) {
System.out.println("B2");
System.out.println("B2 : " + e.toString());
}
}
};
thread2.start();
thread2.interrupt();
//在线程wait状态下进行中断,其中wait()没有在同步块中
Thread thread3 = new Thread(){
public void run(){
try {
this.wait(5000);
System.out.println("A3");
} catch (Exception e) {
System.out.println("B3");
System.out.println("B3 : " + e.toString());
}
}
};
thread3.start();
thread3.interrupt();
//在线程wait状态下进行中断,其中wait()在同步块中
Thread thread4 = new Thread(){
public void run(){
try {
synchronized(this){
this.wait(5000);
System.out.println("A4");}
} catch (Exception e) {
System.out.println("B4");
System.out.println("B4 : " + e.toString());
}
}
};
thread4.start();
thread4.interrupt();
// join阻塞时进行中断
Thread thread5 = new Thread() {
public void run() {
try {
this.join(5000);
System.out.println("A5");
} catch (Exception e) {
System.out.println("B5");
System.out.println("B5 : " + e.toString());
}
}
};
thread5.start();
thread5.interrupt();
}
}输出结果:B2 B4 B4 : java.lang.InterruptedException B3 B3 : java.lang.IllegalMonitorStateException B5 B2 : java.lang.InterruptedException: sleep interrupted B5 : java.lang.InterruptedException A1结果分析:
public class TestCallable implements Runnable {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
public void stop() {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (true) {
System.out.println("线程开始执行...");
String cmd = reader.readLine();
}
} catch (IOException e) {
System.out.println("IO异常,线程结束。");
e.printStackTrace();
}
}
public static void main(String[] args) {
TestCallable callable = new TestCallable();
Thread th = new Thread(callable);
th.start();
callable.stop();
}
}通过关闭通道,抛出一个异常来中断阻塞,达到终止线程的目的。对于网络IO也是如此。public void run() {
while(!Thread.currentThread().isInterrupted()) {
...
}
}public class TestCallable implements Runnable {
// 不管是不是阻塞情况,都用标志变量控制线程循环
private boolean running;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
/**
* 用一个函数封装终止线程的操作
*/
public void stop() {
running = false;
/*
* 针对线程中出现的阻塞情况,使用相应的中断方法。
* 如线程的WAITTING,TIME_WAITTING状态,可以用interrupted()
* 对IO阻塞,可以关闭IO通道等。
*/
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
running = true;
while (running) {
System.out.println("线程开始执行...");
String cmd = reader.readLine();
}
} catch (IOException e) {
System.out.println("IO异常,线程结束。");
e.printStackTrace();
}
}
public static void main(String[] args) {
TestCallable callable = new TestCallable();
Thread th = new Thread(callable);
th.start();
callable.stop();
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/linux2_scdn/article/details/48052153