2016-07-07 50 views
0

我在一個統一的項目合作,實現了德州撲克遊戲從ActionListener的拋出運行時異常。如果沒有收到任何輸入,我一直在等待用戶輸入(從GUI)停止遊戲,然後玩家將被摺疊。 我的初始代碼剛剛在遊戲線程上調用sleep(),然後從控制器調用notify()。我用這種方法遇到的問題是我無法確定控制器是否已通知或睡眠已經結束。 爲了試圖標記這一點,我讓控制器拋出了一個RuntimeException,但在試圖在遊戲線程中發現這個異常時遇到了很多麻煩。趕上在等待了Runnable

這是我最小的可行例如:

GUI.java

import java.awt.GraphicsConfiguration; 
import java.awt.HeadlessException; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class GUI extends JFrame 
{ 
    private JButton jb; 
    private JPanel jp; 
    private WaitTest wt; 

    public GUI(WaitTest wt) throws HeadlessException 
    { 
     // TODO Auto-generated constructor stub 
     this.wt = wt; 
     jp = new JPanel(); 
     jb = new JButton("Throw Runtime"); 
     jp.add(jb); 
     jb.addActionListener(new TestController(wt)); 
     this.add(jp); 
     pack(); 
     this.setVisible(true); 
    } 

    public GUI(GraphicsConfiguration gc) 
    { 
     super(gc); 
     // TODO Auto-generated constructor stub 
    } 

    public GUI(String title) throws HeadlessException 
    { 
     super(title); 
     // TODO Auto-generated constructor stub 
    } 

    public GUI(String title, GraphicsConfiguration gc) 
    { 
     super(title, gc); 
     // TODO Auto-generated constructor stub 
    } 

} 

TestController.java

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class TestController implements ActionListener 
{ 
    private WaitTest wt; 

    public TestController(WaitTest wt) 
    { 
     this.wt = wt; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e){ 
     // TODO Auto-generated method stub 
     System.out.println("Controller throws runtime"); 
     synchronized(wt.getT()) 
     { 
      throw new RuntimeException("Runtime flying"); 
     } 
    } 
} 

WaitTest.java

import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 

public class WaitTest implements Runnable 
{ 
    private Thread t; 

    public WaitTest() 
    { 
     // TODO Auto-generated constructor stub 
     this.t = new Thread(); 
    } 

    public Thread getT() 
    { 
     return t; 
    } 

    public void run() 
    { 
     try 
     { 
      synchronized (this) 
      { 
       Thread.sleep(3000); 
       System.out.println("Player folded"); 
      } 
     } 
     catch (InterruptedException e) 
     { 
      // TODO Auto-generated catch block 

      System.out.println("Caught "); 
     } 

     System.out.println("interupt not received"); 

    } 

    public void test() throws InterruptedException 
    { 
     // TODO Auto-generated method stub 
     ExecutorService executor = Executors.newSingleThreadExecutor(); 
     synchronized (t) 
     { 
      Future<?> future = executor.submit(this); 
      try 
      { 
       future.get(); 
      } 
      catch (ExecutionException e) 
      { 
       System.out.println("hooray!! runtime caught"); 
       t.notify(); 
       return; 
      } 
      catch (Exception ex) 
      { 
       System.out.println("Runtime caught"); 
       t.notify(); 
       return; 

      } 
     } 
    } 

} 

Driver.java

public class driver 
{ 

    public driver() 
    { 
     // TODO Auto-generated constructor stub 
    } 

    public static void main(String[] args) throws InterruptedException 
    { 
     // TODO Auto-generated method stub 
     WaitTest wt = new WaitTest(); 
     GUI gui = new GUI(wt); 
     wt.test(); 
     gui.repaint(); 

    } 
} 

運行時的例外是沒有抓到有一個簡單的方法來抓住這個?還是有更好的方法來停止遊戲循環並等待輸入?這是我第一次嘗試線程控制/併發性,所以我可能忽略了一些簡單的事情

回答

0

我能夠通過將WaitTest轉換爲擴展TimerTask(實現Runnable)並將Thread()更改爲Timer()來解決此問題。

然後在控制器的需要,而不是拋出一個運行時異常我剛打電話cancel()計時器

這是我的目的,有關與執行人和異常

WaitTest.java現在看起來碴乾淨多了像這樣:

import java.util.Timer; 
import java.util.TimerTask; 

public class WaitTest extends TimerTask 
{ 
    private Timer t; 

    public WaitTest() 
    { 
     // TODO Auto-generated constructor stub 
     this.t = new Timer(true); 
    } 
    public void run() 
    { 
     System.out.println("Player folded"); 

    } 

    public void test() 
    { 
     // Schedule task for 5 sec time unless the 
     // controller cancels 
     t.schedule(this, 5000); 

    } 

    public Timer getT() 
    { 
     return t; 
    } 

}