本文介绍了锁定 Runnable 直到完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using Runnable as a loop in Android. As this:

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

每速率"毫秒运行一次.

Which runs every 'Rate' milliseconds.

looper 是这样的:

The looper is as this:

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() 中的代码直到它完成,这样如果它在完成之前被调用 - 调用的线程将返回并完成.

I would like to lock the code inside run() until it is finished, so that if it is called before finished - the thread that calls will return and finish.

我在 run() 中尝试了 synchronized(Object) 方法,但没有用.也试过一个互斥锁,也没用.

I've tried a synchronized(Object) approach inside run() which didn't work. Also tried a Mutex, which also didn't work.

帮助:)

推荐答案

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

The looper object is solely owned by the timer.schedule so no-one can call that object's run method except the timer.schedule. If the run method takes longer that the period you have specified then it is likely that the run method will be called again before it completes - especially since you have passed off the actual running of the the task to the UI thread.

您有两个简单的选择:

  1. 在您的 run 方法中设置一个标志,表明您正在运行,如果设置了,则使 run 什么都不做.
  2. 仅在固定延迟后触发计时器,而不是重复时间.运行结束时,再次将其关闭.
  1. Set a flag in your run method indicating that you are running and make run do nothing if it is set.
  2. Fire off the timer after a fixed delay only, not with a repeat time. At the end of your run, fire it off again.

对于 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));
      }

    });

  }

}

这篇关于锁定 Runnable 直到完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 23:22