停止已经运行的线程

问题描述 投票:1回答:2

我有两个API:一个启动线程,另一个停止线程。我通过调用/start API成功地启动了一个线程,但是我无法通过调用/stop API来停止已经运行的线程。好像Executor#stop()什么都不做。

我的RestController

@Autowired
private Executor executor;

@RequestMapping(path = "/start", method = GET)
public ResponseEntity<HttpStatus> startLongTask() {
    executor.start();
    return ResponseEntity.ok(HttpStatus.OK);
}

@RequestMapping(path = "/stop", method = GET)
public ResponseEntity<HttpStatus> stopLongTask() {
    executor.stop();
    return ResponseEntity.ok(HttpStatus.OK);
}

我的Executor

@Component
public class Executor {

    @Value("${threads.number}")
    private int threadsNumber;

    private ExecutorService executorService;

    @Autowired
    private OtherService otherService;

    @PostConstruct
    private void init() {
        executorService = Executors.newFixedThreadPool(threadsNumber);
        executorService = Executors.newScheduledThreadPool(threadsNumber);
    }

    /**
     * Start.
     */
    public void start() {
        executorService.submit(() -> otherService.methodImExecuting());
    }

    /**
     * Stop.
     */
    @PreDestroy
    publicvoid stop() {
        executorService.shutdownNow();
        try {
            if (!executorService.awaitTermination(800, TimeUnit.MILLISECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }
    }
}

这是methodImExecuting

@Component
public class OtherService {

    public void methodImExecuting() {
        List<SomeObject> dataList = repository.getDataThatNeedsToBeFilled();
        for (SomeObject someObject : dataList) {
            gatewayService.sendDataToOtherResourceViaHttp(someObject);
        }
    }
}
java multithreading spring-boot executorservice
2个回答
2
投票

简短回答:你无法阻止不合作的正在运行的线程。对于线程,有一种弃用的destroy()方法,但这会导致VM的“坏”状态。

结束Thread清理的唯一可能是中断它。但检查中断是线程本身的任务。

所以你的qazxsw大便应该是这样的:

methodImExcecuting

这取决于你的实现你必须查看你的线程是否被中断的频率。但事实是,void methodImExecuting() throws InterruptedException { // it depends on your implementation, I assume here that you iterate // over a collection for example int loopCount = 0; for (Foo foo : foos) { ++loopCount; if (loopCount % 100 == 0) { if (Thread.interrupted()) throw new InterruptedException(); } ... } 的调用只会设置当前在executorService中运行的所有线程的executorService.shutdownNow();标志。要真正中断线程,线程必须自己检查是否设置了interrupted标志,然后抛出一个interrupted


1
投票

您的运行线程必须对中断信号作出反应

InterruptedException

否则发送中断信号无效。

在这里你可以找到一个很好的解释:Thread.currentThread().isInterrupted()

© www.soinside.com 2019 - 2024. All rights reserved.