2010-06-23 26 views
3

下面的代碼是模擬我正在使用的機器人模擬器。我不完全確定爲什麼這不起作用 - 我對線程不是很熟悉,即使我今天嘗試了大量的閱讀,但我似乎沒有取得進展。問題是,一旦調用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; 
    } 
} 

回答

4

您對'pauseDistanceSensor'的調用會阻塞等待調用的主線程。

此外,您的傳感器運行方法只設置一次傳感器值; run方法應該循環,每次都要設置這個值。

您的暫停方法應改爲使用布爾標誌或類似方法調用掛起傳感器運行循環的同步方法。

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();} 
} 
+0

當我昨天晚上讀到這個消息時,我以爲你已經死了。我今天早上跑了它,這是輸出.. 從1277311524656/1:1391/2:475 /等待距離傳感器和3個getDistance呼叫,然後休眠主線程1秒 - 所有3 getDistance調用應打印時睡眠結束/ 3:114/4:114/5:114 /活!通知線程/完成1277311527716 我想通過暫停DistanceSensor的線程在「生存!通知線程」後顯示打印消息。 – nathas 2010-06-23 16:46:39

+0

您必須將打印件移動到傳感器線程中。暫停傳感器不會暫停印刷完成時的主線程 - 如果已完成,則在主線程恢復之前不會暫停打印調用。 – sje397 2010-06-23 23:25:54

相關問題