相关疑难解决方法(0)

在ScheduledExecutorService中运行的任务本身内停止定期任务

在ScheduledExecutorService中运行时,是否有一种很好的方法可以阻止任务内部重复任务?

可以说,我有以下任务:

Future<?> f = scheduledExecutor.scheduleAtFixedRate(new Runnable() {
    int count = 0;
    public void run() {
       System.out.println(count++);
       if (count == 10) {
           // ??? cancel self
       }
    }
}, 1, 1, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

从外面看,很容易通过f.cancel()取消,但是如何在指定的地方停止重复?(通过AtomicReference传递Future是不安全的,因为当scheduleAtFixedRate返回f迟到且变量设置得太晚时,有一个潜在的窗口,并且任务本身可能已经运行,在引用中看到null.)

java concurrency anonymous-class executorservice variable-initialization

21
推荐指数
2
解决办法
1万
查看次数

如何等待(固定利率)ScheduledFuture 在取消时完成

是否有一种内置方法可以取消Runnable已通过固定速率安排的任务ScheduledExecutorService.scheduleAtFixedRate并等待它完成(如果它在调用取消时碰巧正在运行)?

考虑以下示例:

public static void main(String[] args) throws InterruptedException, ExecutionException  {

    Runnable fiveSecondTask = new Runnable() {
        @Override
        public void run() {
            System.out.println("5 second task started");
            long finishTime = System.currentTimeMillis() + 5_000;
            while (System.currentTimeMillis() < finishTime);
            System.out.println("5 second task finished");
        }
    };

    ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
    ScheduledFuture<?> fut = exec.scheduleAtFixedRate(fiveSecondTask, 0, 1, TimeUnit.SECONDS);

    Thread.sleep(1_000);
    System.out.print("Cancelling task..");
    fut.cancel(true);

    System.out.println("done");
    System.out.println("isCancelled : " + fut.isCancelled());
    System.out.println("isDone      : " + fut.isDone());
    try {
        fut.get();
        System.out.println("get         : didn't throw exception"); …
Run Code Online (Sandbox Code Playgroud)

java scheduledexecutorservice

6
推荐指数
1
解决办法
3040
查看次数

更改线程池中一个线程的延迟

我为我的线程池添加了三个具有不同任务和不同延迟的线程,一切正常.

static ScheduledExecutorService scheduleTaskExecutor;
static ScheduledFuture<?> future1;
static ScheduledFuture<?> future2;
static ScheduledFuture<?> future3;

public void onCreate(Bundle savedInstanceState) {
    scheduleTaskExecutor = Executors.newScheduledThreadPool(3);
    future1 = scheduleTaskExecutor.scheduleWithFixedDelay(new Runnable1() {...}, 0, olddelay1, TimeUnit.SECONDS); // Task 1
    future2 = scheduleTaskExecutor.scheduleWithFixedDelay(new Runnable2() {...}, 0, olddelay2, TimeUnit.SECONDS); // Task 2
    future3 = scheduleTaskExecutor.scheduleWithFixedDelay(new Runnable3() {...}, 0, olddelay3, TimeUnit.SECONDS); // Task 3
}
Run Code Online (Sandbox Code Playgroud)

稍后在运行时我希望更改其中一个线程的延迟(无论哪个),其他线程将继续使用旧的延迟.我认为ScheduledFuture引用可以帮助并尝试以下代码(例如第二个线程),但是在执行之后,线程池中只剩下一个线程(任务2).

public void changeDelay2(int newdelay2){
    future2.cancel(true);
    future2 = scheduleTaskExecutor.scheduleWithFixedDelay(new Runnable2() {...}, 0, newdelay2, TimeUnit.SECONDS); // Task 2
}
Run Code Online (Sandbox Code Playgroud)

那么是否有可能只改变一个线程的延迟?

java multithreading delay threadpool scheduledexecutorservice

5
推荐指数
1
解决办法
691
查看次数

执行者与线程

我正在尝试运行以下代码:

public static void main(String[] args){
    ScheduledExecutorService service = new ScheduledThreadPoolExecutor(2);

    Runnable r = new Runnable() {
        @Override
        public void run() {
            throw new RuntimeException();
        }
    };
    service.execute(r );
    ScheduledFuture<?> schedule = service.schedule(r, 0, TimeUnit.SECONDS);
    new Thread(r).run();
}
Run Code Online (Sandbox Code Playgroud)

关于上述问题,我有以下问题:

  1. 有没有办法捕获并响应执行程序线程上发生的异常?
  2. 为什么创建的线程的异常显式传播到主线程,但是使用执行程序服务的两个执行都不会传播该错误?怎么能发现这个错误?

编辑:进一步的问题浮现在脑海中:

  1. 如何停止我安排的特定周期性任务,比如在N次重复或N分钟之后?

java multithreading executorservice

4
推荐指数
2
解决办法
1604
查看次数