中断线程最好的,最受推荐的方式是,使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量,然后有秩序地中止任务。Example2描述了这一方式:
class Example2 extends Thread { volatile boolean stop = false;// 线程中断信号量 public static void main(String args[]) throws Exception { Example2 thread = new Example2(); System.out.println("Starting thread..."); thread.start(); Thread.sleep(3000); System.out.println("Asking thread to stop..."); // 设置中断信号量 thread.stop = true; Thread.sleep(3000); System.out.println("Stopping application..."); } public void run() { // 每隔一秒检测一下中断信号量 while (!stop) { System.out.println("Thread is running..."); long time = System.currentTimeMillis(); /* * 使用while循环模拟 sleep 方法,这里不要使用sleep,否则在阻塞时会 抛 * interruptedException异常而退出循环,这样while检测stop条件就不会执行, * 失去了意义。 */ while ((System.currentTimeMillis() - time < 1000)) {} } System.out.println("Thread exiting under request..."); } }
虽然Example2该方法要求一些编码,但并不难实现。同时,它给予线程机会进行必要的清理工作。这里需注意一点的是需将共享变量定义成volatile 类型或将对它的一切访问封入同步的块/方法(synchronized blocks/methods)中。上面是中断一个非阻塞状态的线程的常见做法,但对非检测isinterrupted()条件会更简洁:
class Example2 extends Thread { public static void main(String args[]) throws Exception { Example2 thread = new Example2(); System.out.println("Starting thread..."); thread.start(); Thread.sleep(3000); System.out.println("Asking thread to stop..."); // 发出中断请求 thread.interrupt(); Thread.sleep(3000); System.out.println("Stopping application..."); } public void run() { // 每隔一秒检测是否设置了中断标示 while (!Thread.currentThread().isinterrupted()) { System.out.println("Thread is running..."); long time = System.currentTimeMillis(); // 使用while循环模拟 sleep while ((System.currentTimeMillis() - time < 1000) ) { } } System.out.println("Thread exiting under request..."); } }
到目前为止一切顺利!但是,当线程等待某些事件发生而被阻塞,又会发生什么?当然,如果线程被阻塞,它便不能核查共享变量,也就不能停止。这在许多情况下会发生,例如调用Object.wait()、ServerSocket.accept()和DatagramSocket.receive()时,这里仅举出一些。
他们都可能永久的阻塞线程。即使发生超时,在超时期满之前持续等待也是不可行和不适当的,所以,要使用某种机制使得线程更早地退出被阻塞的状态。下面就来看一下中断阻塞线程技术。
Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是,设置线程的中断标示位,程受到阻塞的地方(如调用sleep、wait、join等地方)抛出一个异常interruptedException,并且中断状态也将被清除,这样线程就得以退出阻塞的状态。下面是具体实现:
class Example3 extends Thread { public static void main(String args[]) throws Exception { Example3 thread = new Example3(); System.out.println("Starting thread..."); thread.start(); Thread.sleep(3000); System.out.println("Asking thread to stop..."); thread.interrupt();// 等中断信号量设置后再调用 Thread.sleep(3000); System.out.println("Stopping application..."); } public void run() { while (!Thread.currentThread().isInterrupted()) { System.out.println("Thread running..."); try { /* * 如果线程阻塞,将不会去检查中断信号量stop变量,所 以thread.interrupt() * 会使阻塞线程从阻塞的地方抛出异常,让阻塞线程从阻塞状态逃离出来,并 * 进行异常块进行 相应的处理 */ Thread.sleep(1000);// 线程阻塞,如果线程收到中断操作信号将抛出异常 } catch (InterruptedException e) { System.out.println("Thread interrupted..."); /* * 如果线程在调用 Object.wait()方法,或者该类的 join() 、sleep()方法 * 过程中受阻,则其中断状态将被清除 */ System.out.println(this.isInterrupted());// false //中不中断由自己决定,如果需要真真中断线程,则需要重新设置中断位,如果 //不需要,则不用调用 Thread.currentThread().interrupt(); } } System.out.println("Thread exiting under request..."); } }
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-20282-2.html
不过如果美国不是没完没了地纠缠
很棒哦