首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Thread的中断机制(2)

Thread的中断机制(2)

中断应用使用中断信号量中断非阻塞状态的线程中断线程最好的,最受推荐的方式是,使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。线程必须周期性的核查这一变量,然后有秩序地中止任务。Example2描述了这一方式:
[url=][/url]
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...");    }}[url=][/url]

使用thread.interrupt()中断非阻塞状态线程虽然Example2该方法要求一些编码,但并不难实现。同时,它给予线程机会进行必要的清理工作。这里需注意一点的是需将共享变量定义成volatile 类型或将对它的一切访问封入同步的块/方法(synchronized blocks/methods)中。上面是中断一个非阻塞状态的线程的常见做法,但对非检测isInterrupted()条件会更简洁:
[url=][/url]
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...");    }}[url=][/url]

到目前为止一切顺利!但是,当线程等待某些事件发生而被阻塞,又会发生什么?当然,如果线程被阻塞,它便不能核查共享变量,也就不能停止。这在许多情况下会发生,例如调用Object.wait()、ServerSocket.accept()和DatagramSocket.receive()时,这里仅举出一些。


他们都可能永久的阻塞线程。即使发生超时,在超时期满之前持续等待也是不可行和不适当的,所以,要使用某种机制使得线程更早地退出被阻塞的状态。下面就来看一下中断阻塞线程技术。
使用thread.interrupt()中断阻塞状态线程Thread.interrupt()方法不会中断一个正在运行的线程。这一方法实际上完成的是,设置线程的中断标示位,在线程受到阻塞的地方(如调用sleep、wait、join等地方)抛出一个异常InterruptedException,并且中断状态也将被清除,这样线程就得以退出阻塞的状态。下面是具体实现:
[url=][/url]
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...");    }}
继承事业,薪火相传
返回列表