2016-04-13 42 views
0

我正在使用javafx進行一個小遊戲(炸彈人)。基本上,我有可以種植炸彈的球員。炸彈持續時間(例如爆炸前1500毫秒)。因此,當我的玩家種植一顆炸彈時,我使用Thread.sleep(ms)啓動了一個炸彈中的線程,並在我通知玩家炸彈爆炸後立即啓動。線程執行期間的對象狀態修改

事情是,我的球員能放下了身上的炸彈再往前......但是,當炸彈爆炸,它與座標通知玩家的情況時,炸彈被種植...

例如,如果我的球員在[2; 2],種植一顆炸彈,然後移動到[2; 4],然後炸彈爆炸,我的球員回到[2; 2] ...

任何人都知道我怎麼能實現我的炸彈指向的玩家實例......?

下面是一個代碼示例:

public class Player{ 
    public void putBomb(){ 
     listBomb.add(new Bomb(this)); 
    } 

    public void refresh(){ 
     System.out.println(xCoordinate+" "+yCoordinate); 
    } 

} 

public class Bomb{ 
    public Bomb(Player p){ 
     observer=p; 

     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(1500); 
        notify(); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
    } 

    public void sendNotification(){ 
     observer.refresh(); 
    } 

} 
+0

通知是對象類中的最終本地方法,您不能在您的類中聲明... – AdamSkywalker

+0

關於您的問題 - 您可以聲明刷新爲同步,這將修復您的可見性問題 – AdamSkywalker

+0

實際上,該方法不是所謂的「通知」,我只是簡化了它。使用synchronized不會改變任何不幸的事情。 – IronRabbit

回答

1

至於你的問題是JavaFX的具體的,如何做到這一點從非GUI Java程序有所不同(因爲JavaFX的已內置併發援助的建議和單線程應用程序編程模型)。您可以使用PauseTransition您不需要其他線程。

public class Bomb{ 
    public Bomb(final Player player){ 
     PauseTransition pause = new PauseTransition(Duration.seconds(1.5)); 
     pause.setOnFinished(event -> player.refresh()); 
     pause.play(); 
    } 
); 

如果由於某種原因你不希望使用的過渡,你想用你自己的線程,那麼你應該看看使用JavaFX concurrency utilitiesTask

如果您不想使用任務,那麼您仍然可以創建自己的線程或可運行,但確保使用Platform.runLater()進行任何回調。例如:

public class Bomb{ 
    public Bomb(final Player player){ 
     new Thread(() -> { 
       try { 
        Thread.sleep(1500); 
        Platform.runLater(() -> player.refresh()); 
       } catch (InterruptedException e) {} 
      } 
     }).start(); 
    } 
} 

不同的方法,我建議過別人PauseTransition的,那麼你就不需要處理併發的詳細信息,如線程,這是很容易出錯。

0

您的跑步方法呼叫[this.]notify()而不是​​on this。我希望它總是會拋出一個IllegalMonitorStateException

而且,在沒有設置其他線程可以檢查的變量的情況下調用notify()幾乎總是一個錯誤。 notify()的問題在於它根本不會執行任何操作,除非某個其他線程碰巧在同一個對象的wait()調用中。沒有適當的同步,你無法保證這是真實的。

這裏只有一個使用wait()notify()正確的方法,那就是在甲骨文調用把守塊的設計模式。 https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html