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)
使用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.Lock和java.util.concurrent.Semaphore.