通常我们会在线程中使用一个标志变量来控制线程的运行,如:
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