在第二线程中无限检查条件

时间:2016-01-13 02:54:48

标签: java eclipse multithreading stack-overflow

我正在创建一个基于文本的Snake游戏,需要无限制地检查我的第二个Thread中的条件是否为真,例如:

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 Exceptions。谢谢!

1 个答案:

答案 0 :(得分:1)

您需要使用两个线程并共享一个信号。我写了一个演示:

import java.util.Scanner;

/**
 * @author heyunxia (love3400wind@163.com)
 * @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
                }
            }
        }
    }
}