暂停恢复线程:Java

时间:2014-12-23 09:10:31

标签: java multithreading resume suspend thread-synchronization

当我运行此代码时,它会显示以下输出:

One : 15 Two : 15 One : 14 Two : 14 Two : 13 One : 13 Two : 12 One : 12 One : 11 Two : 11 Thread 1 suspended Two : 10 Two : 9 Two : 8 Two : 7 Two : 6 Thread 1 resumed Thread 2 suspended Thread 2 resumed

输出不会持续到结束 一:1 二:1 NewThread1类的 myresume 方法是否未执行?这背后的原因是什么?

以下是NewThread1的代码:

class NewThread1 implements Runnable{
String name;
Thread t;
boolean suspendFlag;

NewThread1(String threadname){
    name = threadname;
    t = new Thread(this, name);
    suspendFlag = false;
    t.start();
}

@Override
public void run(){
    try{ 
         for(int i=15; i>0; i--){
             System.out.println(name+ " : " +i);
             Thread.sleep(200);
                synchronized(this){
                    while(suspendFlag){
                        wait();
                    }
                }
        }
    }catch(InterruptedException e){
        System.out.println("New thread1 Interrupted");
    }
}
synchronized void myresume(){
    suspendFlag = false;
}
void mysuspend(){
    suspendFlag = true;
}
}        

以下是NewThread1的代码:(此处定义了main()方法)

public class Suspend_ResumeThreads {
public static void main(String args[]){
    NewThread1 ob1 = new NewThread1("One ");
    NewThread1 ob2 = new NewThread1("Two ");

    try{
        Thread.sleep(1000);
        ob1.mysuspend();
        System.out.println("Thread 1 suspended");
        Thread.sleep(1000);
        ob1.myresume();
        System.out.println("Thread 1 resumed");

        ob2.mysuspend();
        System.out.println("Thread 2 suspended");
        Thread.sleep(1000);
        ob2.myresume();
        System.out.println("Thread 2 resumed");

    }catch(InterruptedException e){
        System.out.println("Main Interrupted");
    }

    try{
        ob1.t.join();
        ob2.t.join();
    }catch(InterruptedException e){
        System.out.println("Main interrupeted in join()");
    }
System.out.println("Main exiting..");    
}
}

1 个答案:

答案 0 :(得分:5)

使用notifyAll来中断wait():put

this.notifyAll();

进入myresume()功能。但是要随时准备好让这个通知迷路;特别是当没有线程正在等待时,它仍然会成功。

确保您在相同的对象上synchronize / wait / notify。一个常见错误是在this上进行同步而没有意识到在匿名内部类的上下文中,this可能是不同的。更糟糕的是,它可以在重构代码时改变!最佳做法是在某处Object lock = new Object();始终synchronize(lock) ... lock.wait(); ... lock.notifyAll();以避免此类编程(和重构)错误。

除非你创建suspendFlag volatile,否则不同的线程也有可能看到该字段的不同值(如果它不是volatile,则线程可能会保留本地副本CPU缓存)。因此,同样使mysuspend同步也是一件好事。

在某些情况下,您可能需要切换到更高级的同步,例如 java.util.concurrent.locks.Lockjava.util.concurrent.Semaphore