捕获从Waiting Runnable中的ActionListener抛出的运行时异常

时间:2016-07-07 06:54:01

标签: java multithreading exception-handling

我正在开发一个Uni项目来实施德州扑克扑克游戏。我一直在努力停止游戏,同时等待用户输入(从GUI),如果没有收到任何输入,那么玩家将被折叠。 我的初始代码在游戏线程上调用sleep(),然后从控制器调用notify()。我用这种方法遇到的问题是我无法判断控制器是否已通知或睡眠已结束。 为了尝试标记这个,我让控制器抛出一个RuntimeException但是在游戏线程中试图捕获这个异常有很多麻烦。

这是我最不可行的例子:

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();

    }
}

从未捕获过运行时异常是否有一种简单的方法来捕获它?或者有更好的方法来停止游戏循环并等待输入?这是我第一次尝试线程控制/并发,所以我可能会忽略一些简单的

1 个答案:

答案 0 :(得分: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;
    }

}