0

我在 Android 中使用 Runnable 作为循环。像这样:

    Timer timer = new Timer();
    timer.schedule(new looper(m_mainView, this),0, Rate);

每“速率”毫秒运行一次。

活套是这样的:

class looper extends TimerTask
{
    private ImageView img;
    Context c;


    public looper(ImageView imgView, Context context)
    {
        this.img = imgView;
        this.c = context;
    }

    public void run()
    {   
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
....

我想将代码锁定在里面run()直到它完成,这样如果在完成之前调用它 - 调用的线程将返回并完成。

我尝试了synchronized(Object)一种内部方法run()无效。还尝试了互斥锁,但也没有用。

帮助 :)

4

3 回答 3

1

looper对象由唯一拥有,timer.schedule因此run除了timer.schedule. 如果该run方法花费的时间比您指定的时间长,那么很可能会在它完成之前再次调用 run 方法 - 特别是因为您已经将任务的实际运行传递给 UI 线程。

你有两个简单的选择:

  1. 在您的方法中设置一个标志,run表明您正在运行,run如果已设置则不执行任何操作。
  2. 仅在固定延迟后触发计时器,而不是重复时间。在运行结束时,再次启动它。

对于 1:

class Looper extends TimerTask {
  // ** Add this **
  volatile boolean running = false;

  public Looper() {
  }

  @Override
  public void run() {
    // ** Add this **
    if (!running) {
      running = true;
      try {
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
          }

        });
        // ** Add this **
      } finally {
        running = false;
      }

    }
  }

}

第二种方法:

timer.schedule(new looper(m_mainView, this, Rate),new Date());
...
class Looper extends TimerTask {
  final long rate;
  final Looper looper;

  public Looper(long rate) {
    this.rate = rate;
    looper = this;
    // ...
  }

  @Override
  public void run() {
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        // ...
        new Timer().schedule(looper, new Date(new Date().getTime() + rate));
      }

    });

  }

}
于 2013-05-16T15:37:27.037 回答
0

您应该synchronized像这样添加到方法声明中:

public synchronized void run()
于 2013-05-16T15:15:10.337 回答
0

首先,为什么会有再次调用run方法的风险?如果这是真的,这对我来说听起来像是设计缺陷。其次,使用ScheduledExecutorService代替TimerTask 可能会更好。这是按固定时间间隔执行计划任务的标准、最简单和最安全的方式。您的用户代码只能从执行程序服务访问,您可以从中获取 ScheduledFuture 以获取返回值,以便您知道任务何时完成(调用 get() 时 ScheduledFuture 会阻塞)。看看 Java Concurrency in Practice 了解更多...

于 2013-05-16T16:03:16.843 回答