내 코드에서 가능한 게임 트리로 깊숙이 들어가서 최선의 움직임을 결정하기 위해 재귀 및 병렬 스트림 처리를 많이 사용하는 작업을 실행해야합니다. 이것은 많은 시간이 걸리므로, 사용자가 컴퓨터가 너무 오랫동안 기다려서 "천천히"1000 밀리 초의 시간을 설정하려고 생각하지 못하게합니다. 1000msec가 넘지 않는 최고의 움직임이 발견되면 컴퓨터는 무작위로 움직입니다. 내 문제는 내가 취소 (true로 설정할 수도 있음)와 함께 미래에 취소를 호출해도 작업이 중단되지 않고 바쁜 스레드가 백그라운드에서 계속 실행된다는 것입니다. 주기적으로 isInterrupted()을 확인한 다음 구제 조치를 시도했지만 도움이되지 않았습니다. 아이디어가 있으십니까?멀티 스레드 바쁜 작업의 미래를 취소하려면 어떻게합니까?
public Move bestMove() {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Move> callable =() -> bestEntry(bestMoves()).getKey();
Future<Move> future = executor.submit(callable);
try {
return future.get(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
System.exit(0);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
future.cancel(true);
return randomMove();
}
return null;
}
private Move randomMove() {
Random random = new Random();
List<Move> moves = state.possibleMoves();
return moves.get(random.nextInt(moves.size()));
}
private <K> Map.Entry<K, Double> bestEntry(Map<K, Double> map) {
List<Map.Entry<K, Double>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (e1, e2) -> (int) (e2.getValue() - e1.getValue()));
return list.get(0);
}
private <K> Map.Entry<K, Double> worstEntry(Map<K, Double> map) {
List<Map.Entry<K, Double>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (e1, e2) -> (int) (e1.getValue() - e2.getValue()));
return list.get(0);
}
private Map<Move, Double> bestMoves() {
Map<Move, Double> moves = new HashMap<>();
state.possibleMoves().stream().parallel().forEach(move -> {
if (!Thread.currentThread().isInterrupted()) {
Game newState = state.playMove(move);
Double score = newState.isTerminal() ? newState.utility()
: worstEntry(new (newState).worstMoves()).getValue();
moves.put(move, score);
}
});
return moves;
}
private Map<Move, Double> worstMoves() {
Map<Move, Double> moves = new HashMap<>();
state.possibleMoves().stream().parallel().forEach(move -> {
if (!Thread.currentThread().isInterrupted()) {
Game newState = state.playMove(move);
Double score = newState.isTerminal() ? -newState.utility()
: bestEntry(new (newState).bestMoves()).getValue();
moves.put(move, score);
}
});
return moves;
}
PS :
아래는 내 코드 나는 또한없이 시도 "병렬()"그러나 다시 하나의 스레드가 계속 실행 여전히 존재한다.
미리 감사드립니다. 당신이 스레드가 실행을 계속 사용할 수있는 경우 count
킵 검사 볼 수 있듯이
public static void main(String[] args) throws InterruptedException {
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<Integer> future = executor.submit(() -> count());
try {
System.out.println(future.get(1, TimeUnit.SECONDS));
} catch (Exception e){
future.cancel(true);
e.printStackTrace();
}finally {
System.out.printf("status=finally, cancelled=%s, done=%s%n", future.isCancelled(), future.isDone());
executor.shutdown();
}
}
static int count() throws InterruptedException {
while (!Thread.interrupted());
throw new InterruptedException();
}
것은, 당신이 이해하는 것이 있습니다
https://techblog.bozho.net/interrupting-executor-tasks/ – MarianP