简体   繁体   English

JAVA:如何在特定时间后停止执行功能?

[英]JAVA: How to stop the execution of a function after a specific time?

I want to implement iterative deepening (incremental tree building). 我想实现迭代加深(增量树构建)。 This is the part of my code I will ask about: 这是我要询问的代码的一部分:

        ExecutorService executorService = Executors.newSingleThreadExecutor();

        Set<Callable<Integer>> callables = new HashSet<Callable<Integer>>();

        callables.add(new Callable<Integer>() {
            public Integer call() throws Exception {
                iterativeDeepening(depthLimit, board);
                return -1;
            }
        });
        callables.add(new Callable<Integer>() {
            public Integer call() throws Exception {
                Thread.sleep(500);
                return 1;
            }
        });
        try{
            executorService.invokeAny(callables, 1000, TimeUnit.MILLISECONDS);
        }catch(TimeoutException | InterruptedException ex){
            executorService.shutdown();
        }

        executorService.shutdown();

From what I read about invokeAny() with time limit it should end executing its Callable objects as soon as the deadline is reached. 从我对有时间限制的invokeAny()的了解中,它应该在达到期限后立即结束执行其Callable对象。 It works when I put long sleep instead of my function iterativeDeepening(depthLimit, board). 当我长时间睡眠而不是我的功能iterativeDeepening(depthLimit,board)时,它可以工作。 How to make it work with my function? 如何使其与我的功能配合工作? Below I paste the code to this function: 下面,我将代码粘贴到此函数:

    public void iterativeDeepening(byte depthLimit, byte[] board){

    for(byte depth=1;depth<depthLimit;depth++){
        GameTree gameTree= new GameTree();
        byte[] tempBoard = new byte[14];
        for(byte i=0;i<14;i++){
            tempBoard[i] = board[i];
        }
        Node <byte[]> root= new Node<byte[]>(tempBoard, player);
        try {
            gameTree.buildGameTree(depth, root);
        } catch (OutOfMemoryError E) {
            gameTree.eraseGameTree(depth,root);
            System.gc();
        }

        MiniMax minimax = new MiniMax(player);
        move= minimax.selectMove(depth, root);

    }
}

If you know a better way to make it or know how to successfully stop execution of my function please let me know. 如果您知道更好的方法或成功停止执行我的函数,请告诉我。 I tried also a Runnable Interface mentioned in this topic: How to stop execution after a certain time in Java? 我还尝试了本主题中提到的Runnable接口: 在Java中经过一定时间后如何停止执行? but it just worked the same. 但它的工作原理相同。

After the timeout is reached, the ExecutorService will try to interrupt all the currently running tasks by calling Thread.interrupt() on them. 达到超时后, ExecutorService将尝试通过在它们上调用Thread.interrupt()来中断所有当前正在运行的任务。 This will put each of the threads to an interrupted state. 这会将每个线程置于中断状态。 sleep() quits when this state is set. 设置此状态后, sleep()退出。

So adding this check: 因此添加此检查:

if(Thread.currentThread().interrupted()) {
    return;
}

inside your function should do the job. 内部的功能应该做的工作。

A tip for you thread termination: 线程终止的提示:

try{
    executorService.invokeAny(callables, 1000, TimeUnit.MILLISECONDS);
} catch(TimeoutException | InterruptedException ex){
    //... ignore
} finally {
    executorService.shutdown();
    executorService.awaitTermination(); <-- add this line if you want to wait for the computation to end
}

UPDATE UPDATE

That's not a solution because inside a loop there is a function gameTree.buildGameTree(depth, root); 这不是解决方案,因为在循环中有一个功能gameTree.buildGameTree(depth,root); which itself sometimes takes longer than the deadline which is crucial. 这本身有时比关键的截止时间要长。

As far as I know, there is no way to interrupt such function from outside. 据我所知,没有办法从外部中断这种功能。 This function should check it's state from time to time. 此功能应不时检查其状态。 If it's a loop, consider checking the state on some or all of the iterations. 如果是循环,请考虑检查部分或全部迭代的状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM