4

我使用 ScheduledExecutorService,我希望它每 10 秒进行一次计算,持续一分钟,然后在那一分钟后返回新值。我该怎么做?

示例:所以它收到 5 它添加 +1 六次然后它应该在一分钟后返回我的值 11。

我到目前为止但没有工作的是:

package com.example.TaxiCabs;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import static java.util.concurrent.TimeUnit.*;


public class WorkingWithTimeActivity {
public int myNr;
public WorkingWithTimeActivity(int nr){
    myNr = nr;
}
private final ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(1);

public int doMathForAMinute() {
    final Runnable math = new Runnable() {
        public void run() {
            myNr++;
        }
    };
    final ScheduledFuture<?> mathHandle =
            scheduler.scheduleAtFixedRate(math, 10, 10, SECONDS);
    scheduler.schedule(
            new Runnable() {
                public void run() {
                    mathHandle.cancel(true);
                }
            }, 60, SECONDS);
    return myNr;
}

}

在我的主要活动中,我希望它在 1 分钟后将我的 txtview 文本更改为 11;

WorkingWithTimeActivity test = new WorkingWithTimeActivity(5);
txtview.setText(String.valueOf(test.doMathForAMinute()));
4

2 回答 2

7

您应该使用Callablewhich can return value 而不是 Runnable

Callable 接口与 Runnable 类似,两者都是为实例可能由另一个线程执行的类设计的。但是,Runnable 不返回结果,也不能抛出检查异常。

public class ScheduledPrinter implements Callable<String> {
    public String call() throws Exception {
        return "somethhing";
    }
}

然后像下面这样使用它

    ScheduledExecutorService scheduler = Executors
            .newScheduledThreadPool(1);
    ScheduledFuture<String> future = scheduler.schedule(
            new ScheduledPrinter(), 10, TimeUnit.SECONDS);
    System.out.println(future.get());

这是一个镜头计划,因此它只会执行一次,一旦返回 get 调用,您将需要再次安排它。


但是,在您的情况下,一旦您的条件到达,就可以很容易地使用一个简单的方法AtomicIntegeraddAndGet比较返回的值,通过调用取消来取消调度。

于 2012-11-01T17:22:23.183 回答
0

如果要从中返回结果doMathForAMinute,则根本不需要 ScheduledExecutorService。只需创建一个运行计算的循环,然后运行 ​​Thread.sleep()。使用 ScheduledExecutorService 的整个想法是释放启动任务的线程等待结果,但在这里你不会释放它。

如果,正如我所怀疑的,调用的线程doMathForAMinute是 GUI 线程,那么这是完全错误的,因为你的 gui 会卡住并且一分钟都没有响应。相反,doMathForAMinute应该只开始并行计算,并且并行任务本身应该使用runOnUiThread或其他方式更新 UI。

也可以看看:

Android:runOnUiThread 并不总是选择正确的线程?

我在哪里创建和使用 ScheduledThreadPoolExecutor、TimerTask 或 Handler?

于 2012-11-01T17:41:32.517 回答