暂停恢复线程:Java

Jai*_*eri 2 java resume multithreading 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

输出不会持续到结束为One:1 Two: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;
}
}        
Run Code Online (Sandbox Code Playgroud)

以下是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..");    
}
}
Run Code Online (Sandbox Code Playgroud)

Ano*_*sse 5

使用notifyAll中断一个wait():把

this.notifyAll();
Run Code Online (Sandbox Code Playgroud)

进入你的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.