我有一个简单的类,它扩展了线程类,它有一个运行方法,如下所示:
public void run() {
while(running) {
if(enabled)
{
doStep();
enabled = false;
}
else
{
try {
this.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
我希望myObject
拨打doStep()
myObject.enbled = true;
但是如何确保myObject
实际上已经完成了doStep()
方法呢?简单
myObject.enable = true
while(myObject.isEnabled())
{
;
}
doActionAfterObjectFinish();
某些时候导致程序卡在循环中,并且肯定doStep()
不会导致它。
@谢谢你的答案而不是使用sempahores woudlnt如果我以这种方式更改代码会有帮助吗?
public void run() {
while(running) {
if(enabled)
{
synchronized(this){
doStep();
enabled = false;
}
}
else
{
try {
this.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public synchronized boolean isEnabled() {
return enabled;
}
答案 0 :(得分:4)
一,确保myObject.enable
变量声明为volatile
。
其中两项,我建议您使用java.util.concurrent
软件包进行建模......可能是Semaphore可以帮助您......
import java.util.concurrent.Semaphore;
public class Example {
public static void main(String[] args) throws InterruptedException {
MyRunnable target = new MyRunnable();
Thread thread2 = new Thread(target);
thread2.start();
target.waitUntilFinish();
System.out.println("MyRunnable ends first!");
}
public static class MyRunnable implements Runnable {
private Semaphore workDone = new Semaphore(0);
private int count;
@Override
public void run() {
while (true) {
// heavy work here...
if (this.count < 5) {
System.out.println("Iteration: " + (++this.count));
} else {
this.workDone.release();
break;
}
try { Thread.sleep(2000L); } catch (InterruptedException ex) { }
}
}
public void waitUntilFinish() throws InterruptedException {
this.workDone.acquire();
}
}
}
答案 1 :(得分:0)
当您在CPU上使用多线程时,强烈建议使用信号量或锁。请看一下:A java's aproach to Spinlocks和Oracle documentation of semaphores。实际上,您必须设置信号量或自旋锁以在需要时阻止代码并在需要时解锁代码。是一种常见的,值得推荐的做法。
可能对你有用的自旋锁伪代码是:
void thread1(){
while(true){
while(locked(lock1));
lock(lock2);
doActions();
unlock(lock2);
}
}
void thread2(){
while(true){
while(locked(spinlock2));
lock(spinlock1);
doStuff();
unlock(spinlock1);
}
}