目前VS.NET2008中Thread.Suspend和Thread.Resume已经过时,可能以后会废弃掉,请问如何实现线程的暂停和恢复的类似功能?最好能有代码,多谢!

解决方案 »

  1.   

    我应该用什么来取代 Thread.suspend 和 Thread.resume ?
    与Thread.stop ,类似,谨慎的方式,是让“目标线程”轮询一个指示线程期望状态(活动或挂起)的变量。当期望状态是挂起时,线程用 Object.wait 来等待;当恢复时,用 Object.notify 来通知目标线程。例如,假设你的applet包含下面的 mousePressed事件句柄,用来切换一个被称为blinker 的线程的状态。
    private boolean threadSuspended;    Public void mousePressed(MouseEvent e) {
            e.consume();        if (threadSuspended)
                blinker.resume();
            else
                blinker.suspend();  // DEADLOCK-PRONE!        threadSuspended = !threadSuspended;
        }
    要避免使用 Thread.suspend 和 Thread.resume , 你可以把上述事件句柄替换为:    public synchronized void mousePressed(MouseEvent e) {
            e.consume();        threadSuspended = !threadSuspended;        if (!threadSuspended)
                notify();
        }
    并把下述代码增加到“运行循环”中:                synchronized(this) {
                        while (threadSuspended)
                            wait();
                    }wait方法抛出 InterruptedException ,因此他必须在一个“ try ... catch” 语句中。使用 sleep 方法时,也可以将其放入同样的语句中。检查应该在sleep 方法后(而不是先于),以便当线程恢复的时候窗口被立即重绘。 修改后的 run 方法如下:    public void run() {
            while (true) {
                try {
                    Thread.currentThread().sleep(interval);                synchronized(this) {
                        while (threadSuspended)
                            wait();
                    }
                } catch (InterruptedException e){
                }
                repaint();
            }
        }
    注意,mousePressed 方法中的 Notify和run方法中的wait都是在 synchronized 语句块中的。这是语言的要求,也确保了 wait 和 notify 被正确串行化执行。从实际效果来看,这消除了竞争条件,避免了不确定的“挂起”线程丢失 notify 消息而仍保持挂起。虽然随着平台的成熟Java的同步开销正在减少,但其永远都不会是免费的。有一个简单的技巧,可以用于移除我们加入到“运行循环”每次迭代中的同步。加入的同步块被替换为稍微有点复杂的代码片段,只有当线程真正被挂起的时候后才会进入同步块:                if (threadSuspended) {
                        synchronized(this) {
                            while (threadSuspended)
                                wait();
                        }
                    }
    由于缺少显式同步, threadSuspended 必须被指定为 volatile 来保证挂起请求被迅速传递。修改后的 run 方法如下:    private boolean volatile threadSuspended;    public void run() {
            while (true) {
                try {
                    Thread.currentThread().sleep(interval);                if (threadSuspended) {
                        synchronized(this) {
                            while (threadSuspended)
                                wait();
                        }
                    }
                } catch (InterruptedException e){
                }
                repaint();
            }
        }