下面的代码是模拟我正在使用的机器人模拟器。我不完全确定为什么这不起作用 - 我对线程不是很熟悉,即使我今天尝试阅读很多,但我似乎并没有取得进展。问题是,一旦调用pauseDistanceSensor(),它就永远不会被唤醒。
import java.util.Random;
public class TestThreads
{
private DistanceSensor dist;
private Thread distanceThread;
public TestThreads()
{
this.dist = new DistanceSensor();
this.distanceThread = new Thread(this.dist);
this.distanceThread.start();
}
public int getDistance()
{
return this.dist.getMeasurement();
}
public void pauseDistanceSensor()
{
synchronized(this.dist)
{
try {
this.dist.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void resumeDistanceSensor()
{
synchronized(this.dist)
{
this.dist.notify();
}
}
public static void main(String[] args)
{
TestThreads test = new TestThreads();
long timestamp = System.currentTimeMillis();
System.out.println("Starting at "+timestamp);
System.out.println("1: "+test.getDistance());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("2: "+test.getDistance());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("waiting distance sensor and making 3 getDistance calls then sleeping main thread for 1 second - all 3 getDistance calls should be printed when the sleep ends");
test.pauseDistanceSensor();
System.out.println("3: "+test.getDistance());
System.out.println("4: "+test.getDistance());
System.out.println("5: "+test.getDistance());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Alive! Notifying the thread");
test.resumeDistanceSensor();
System.out.println("Done at "+System.currentTimeMillis());
}
}
class DistanceSensor implements Runnable
{
private final Random gen = new Random(54);
private int currentVal;
public DistanceSensor()
{
this.currentVal = this.gen.nextInt(1500);
}
public void run()
{
this.currentVal = this.gen.nextInt(1500);
}
public int getMeasurement()
{
return this.currentVal;
}
}
答案 0 :(得分:4)
您对'pauseDistanceSensor'的调用会阻止等待呼叫中的主线程。
此外,您的传感器运行方法仅设置传感器值一次; run方法应该循环,每次都设置值。
你的pause方法应该调用一个使用布尔标志或类似方法挂起传感器运行循环的synchronized方法。
import java.util.Random;
public class TestThreads
{
private DistanceSensor dist;
private Thread distanceThread;
public TestThreads()
{
this.dist = new DistanceSensor();
this.distanceThread = new Thread(this.dist);
this.distanceThread.start();
}
public int getDistance()
{
return this.dist.getMeasurement();
}
public void pauseDistanceSensor()
{
dist.setPaused(true);
}
public void resumeDistanceSensor()
{
dist.setPaused(false);
}
public void finish() {
dist.setDone();
}
public static void main(String[] args)
{
TestThreads test = new TestThreads();
long timestamp = System.currentTimeMillis();
System.out.println("Starting at "+timestamp);
System.out.println("1: "+test.getDistance());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("2: "+test.getDistance());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("waiting distance sensor and making 3 getDistance calls then sleeping main thread for 1 second - all 3 getDistance calls should be printed when the sleep ends");
test.pauseDistanceSensor();
System.out.println("3: "+test.getDistance());
System.out.println("4: "+test.getDistance());
System.out.println("5: "+test.getDistance());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Alive! Notifying the thread");
test.resumeDistanceSensor();
System.out.println("Done at "+System.currentTimeMillis());
test.finish();
}
}
class DistanceSensor implements Runnable
{
private final Random gen = new Random(54);
private int currentVal;
private boolean done = false, paused = false;
public DistanceSensor()
{
this.currentVal = this.gen.nextInt(1500);
}
public void run()
{
while(!getDone()) {
if(!getPaused()) synchronized(this) {this.currentVal = this.gen.nextInt(1500);}
synchronized(this) {
try {
wait(500);
} catch(InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
public synchronized int getMeasurement()
{
return this.currentVal;
}
public synchronized boolean getPaused() {return paused;}
public synchronized boolean getDone() {return done;}
public synchronized void setPaused(boolean p) {paused = p;}
public synchronized void setDone() {done = true;notify();}
}