2016-01-13 11 views
0

我創建一個基於文本的貪吃蛇遊戲,並需要無限檢查,看是否有狀況是我的第二個主題真實的,例如:無限檢查條件在第二個線程

while(true) 
{ 
    if(Snake.moveY == 1) 
    { 
     //Do something 
    } 
    if(Snake.moveY == -1) 
    { 
     //Do something 
    } 
    if(Snake.moveX == 1) 
    { 
     //Do something 
    } 
    if(Snake.moveX == -1) 
    { 
     //Do something 
    } 
} 

然而,這導致StackOverflow異常,並從未實際運行。我想知道如何經常檢查而不拋出異常。我意識到這已被問Here,但是沒有任何答案是足夠的,並導致StackOverflow異常。謝謝!

+1

你可以添加stacktrace嗎? – scsere

+0

如果你繼續使用while(true)你將stackoverflow嘗試在while循環中添加另一個條件 – Abdelhak

+0

是否還有其他可能導致錯誤的內容?您是否在某處使用遞歸方法?因爲這對我來說似乎很好。 – scsere

回答

1

您需要使用兩個線程並共享一個信號。我寫了一個演示:

import java.util.Scanner; 

/** 
* @author heyunxia ([email protected]) 
* @version 1.0 
* @since 2016-01-13 下午2:48 
*/ 

public class MainGame { 
    final MyWaitNotify myWaitNotify = new MyWaitNotify(); 

    public static void main(String[] args) { 

     final MainGame game = new MainGame(); 
     game.go(); 
     /**/ 


    } 

    public void go() { 

     IWorkingThread workingThread = new IWorkingThread() { 
      @Override 
      public void execute() { 
       if ("top".equals(myWaitNotify.getStep())) { 
        //todo top 
        System.out.println("moving top..."); 
       } else if ("bottom".equals(myWaitNotify.getStep())) { 
        //todo bottom 
        System.out.println("moving bottom..."); 
       } else if ("left".equals(myWaitNotify.getStep())) { 
        //todo left 
        System.out.println("moving left..."); 
       } else if ("right".equals(myWaitNotify.getStep())) { 
        //todo right 
        System.out.println("moving right..."); 
       } 
      } 
     }; 
     ControlThread controlThread = new ControlThread(myWaitNotify, workingThread); 
     controlThread.start(); 



     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (true) { 
        Scanner cin=new Scanner(System.in); 
        System.out.println("please input:"); 
        String name=cin.nextLine(); 
        signal(name); 
       } 
      } 
     }).start(); 
    } 

    private void signal(String step){ 
     myWaitNotify.setStep(step); 
     //very important 
     myWaitNotify.doNotify(); 
    } 


    interface IWorkingThread { 
     void execute(); 
    } 


    class MonitorObject { 
    } 

    class MyWaitNotify { 
     MonitorObject myMonitorObject = new MonitorObject(); 
     boolean wasSignalled = false; 
     private String step = "sleep"; // default single : sleep 

     public String getStep() { 
      return step; 
     } 

     public void setStep(String step) { 
      this.step = step; 
     } 

     public void doWait() { 
      synchronized (myMonitorObject) { 
       while (!wasSignalled) { 
        try { 
         myMonitorObject.wait(); 
        } catch (InterruptedException e) { 
        } 
       } 
       wasSignalled = false; 
      } 
     } 

     public void doNotify() { 
      synchronized (myMonitorObject) { 
       wasSignalled = true; 
       myMonitorObject.notify(); 
      } 
     } 
    } 


    class ControlThread extends Thread { 
     private MyWaitNotify waitNotify; 
     private IWorkingThread workingThread; 

     public ControlThread(MyWaitNotify waitNotify, IWorkingThread workingThread) { 
      this.waitNotify = waitNotify; 
      this.workingThread = workingThread; 
     } 

     public void run() { 
      while (true) { 
       //System.out.println(); 
       System.out.println(waitNotify.getStep()); 
       waitNotify.doWait(); 
       if ("#left#right#top#bottom".contains(waitNotify.getStep())) { 
        this.workingThread.execute(); 
       } else /* exit */ {//game over 
        //todo exit code 
       } 
      } 
     } 
    } 
}