如何中断“同步/阻塞”线程,not only interrupt()

如何中断一个正在执行的线程?

线程中断,意味着该线程在完成任务之前停止其正在进行的一切,有效地中止其当前的操作。

那么,线程接下为是死亡、还是等待新的任务,或是继续运行至下一步。

 

【方法一】使用共享变量Shared Variable

1. 需要线程“周期性”的核查这一变量,然后有秩序的中止任务。

2. 将共享变量定义成“volatile”型,或将它的一切方法封入“synchronized”块或方法中。

3. 局限性:如果线程被阻塞,便不能核查共享变量,该方法将失效。例如,Object.wait(), ServerSocket.accept()和DatagramSocket.receive(),等等。

 

public class Main extends Thread {
 
    volatile boolean stop = false;
 
    public static void main(String[] args) {
 
        Main thread = new Main();
 
        try {
            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");
        } catch (InterruptedException e) {
            System.out.println("sleep interrupted");
            ;
        }
    }
 
    public void run() {
        while (!stop) { // 周期性的检查
            System.out.println("running");
            long time = System.currentTimeMillis();
            while (System.currentTimeMillis() - time < 1000) {
                ;
            }
        }
        System.out.println("thread exiting under request..");
    }
}

 

 

【方法二】对于阻塞情况,使用Thread.interrupt()

(1)interrupt(),不会中断一个正在运行的线程,它实际完成的是,在线程“受到阻塞时”抛出一个中断信号,这样线程就得以退出阻塞状态。更确定的说,如果线程被Object.wait(), Thread.join()和Thread.sleep()三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。

(2)局限性:interrupt(),可以很好的解救阻塞中的线程,但如果一直占用着CPU就仍然中断不了.

public class Main extends Thread {
    boolean stop = false;
    public static void main(String[] args) {
        Main thread = new Main();
        try {
            System.out.println("starting thread");
            thread.start();
            Thread.sleep(3000);
            System.out.println("asking thread to stop");
            thread.stop = true; // 如果线程阻塞,将不会检查此变量
            thread.interrupt(); // 中断
            Thread.sleep(3000);
            System.out.println("stopping application");
        } catch (InterruptedException e) {
            System.out.println("sleep interrupted");
            ;
        }
    }
 
    public void run() {
        while (!stop) {
            System.out.println("running");
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                System.out.println("Thread interrupted");
            }
        }
        System.out.println("thread exiting under request..");
    }
}

 

【方法三】“野蛮”行径,未尝不可

(1)对于同步情况,可以开“捣乱”线程,强抛RuntimeException

例如,同步等待在主线程A中做,那么:

a) 在A中中开线程B,做的事情:sleep(timeout)时间,醒了就抛出RuntimeException;

b) 在A中做一些事情,同步神马的亦可;

c) timeout时间到,若2)仍未结束,RuntimeException也会使其结束的;

(2)劣势:这种方法,强抛runtimeException出来,无法catch,自然也就意味着不能做任何处理,眼睁睁的看着它抛。

 

Semaphore s = new Semaphore(0);
TimeoutThread t = new TimeoutThread(5000L, new TimeoutException("超时"));
try {
    t.start();
    
    // 同步等待代码
    System.out.println("try to acquire");
    s.acquire();
    System.out.println("acquired");
    
    t.cancel();
}catch (InterruptedException e) {
    System.out.println("interrupt exception");
}

 

【方法四】……

 

 

 

【备注】:

(1)不推荐使用:Thread.stop()

(2)这样使用interrupt,并不能真正中断线程,所以不要被名字蒙蔽了:

public class Main extends Thread {
 
    volatile boolean stop = false;
 
    public static void main(String[] args) {
 
        Main thread = new Main();
 
        try {
            System.out.println("starting thread");
            thread.start();
            Thread.sleep(3000);
            System.out.println("Interrupting thread");
            thread.interrupt(); // 线程并没有真正被中断,只是置了中断位
            Thread.sleep(3000);
            System.out.println("stopping application");
        } catch (InterruptedException e) {
            System.out.println("sleep interrupted");
            ;
        }
 
    }
 
    public void run() {
        while (!stop) {
            System.out.println("running");
            long time = System.currentTimeMillis();// 这样的操作,一直占用着CPU,非"阻塞",所以interrupt()对其无用,不生效.
            while (System.currentTimeMillis() - time < 1000) {
                ;
            }
        }
        System.out.println("thread exiting under request..");
    }
 
}

 

 

 

 

http://wenku.baidu.com/view/1586ccea81c758f5f61f6751.html

http://java.chinaitlab.com/base/786639.html

posted @ 2012-06-11 13:33  技术草根女  Views(543)  Comments(0Edit  收藏  举报