简体   繁体   English

在UI中执行按钮操作时停止ScheduledExecutorService

[英]Stopping ScheduledExecutorService when button action is performed in the UI

I have created a scheduledExecutorService as below 我创建了一个scheduledExecutorService如下

ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(new Runnable() {
  @Override
  public void run() {
    // do stuff
  }
}, 0, 5, TimeUnit.SECONDS);

I would like to stop service when stop button is clicked in the UI or JSP . UIJSP单击停止按钮时,我想停止服务。 Any help on this is so much appreciated 在这方面的任何帮助都非常感谢

ScheduledFuture::cancel

When calling ScheduledExecutorService::scheduleAtFixedRate , you get back a ScheduledFuture . 调用ScheduledExecutorService::scheduleAtFixedRate ,您将获得ScheduledFuture Currently your code ignores that returned object, and drops it. 当前,您的代码将忽略该返回的对象,并将其删除。

Change your code to capture that scheduled future object. 更改代码以捕获该计划的将来对象。

ScheduledFuture future = exec.scheduleAtFixedRate(… 

The ScheduledFuture has methods to cancel the task, and to ask if the task is already cancelled . ScheduledFuture具有一些方法来取消任务,并询问任务是否已经取消

Take a look at shutdownNow() method of the executor. 看一下执行器的shutdownNow()方法。

exec.shutdownNow();
exec.awaitTermination();

It does almost what you want. 几乎可以满足您的要求。 It does not stop the thread immediately (cause it's not safe). 它不会立即停止线程(因为它不安全)。 Instead it sets isInterrupted() flag notifying the running thread that is should stop. 而是设置isInterrupted()标志来通知正在停止的正在运行的线程。 So, your Runnable has to check for that flag from time to time. 因此,您的Runnable必须不时检查该标志。 And when it finds the flag is set, it should return from the run() method. 并且当发现标志被设置时,它应该从run()方法返回。

exec.awaitTermination(); is waiting until the thread is stopped. 正在等待直到线程停止。 After that line you may be sure that the thread has stopped execution. 在那一行之后,您可以确定线程已停止执行。

Create a class with a flag variable. 创建一个带有标志变量的类。 Check the value of that flag and stop the thread if needed. 检查该标志的值,并在需要时停止线程。

public class MyRunnable implements Runnable {
   private AtomicBoolean running = new AtomicBoolean(true);

   public void run() {
       while (running.get()) {
          ...
       }
   }

   public void stopMe() {
      running.set(false);
   }
} 


ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
MyRunnable myRunnable = new MyRunnable();
exec.scheduleAtFixedRate(myRunnable, 0, 5, TimeUnit.SECONDS);

...
myRunnable.stopMe();

Note: use an AtomicBoolean so you are sure to not have a side effect setting and checking the value of running variable in a multithread environment: 注意:请使用AtomicBoolean因此确保在多线程环境中没有副作用设置并检查running变量的值:

A boolean value that may be updated atomically. 一个可以自动更新的布尔值。

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

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