我在Android中使用Runnable作为循环。就这样:
Timer timer = new Timer();
timer.schedule(new looper(m_mainView, this),0, Rate);
每个'Rate'毫秒运行。
looper就是这样:
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()
方法但没有效果。还尝试了一个Mutex,它也没有用。
帮助:)
答案 0 :(得分:1)
looper
对象完全归timer.schedule
所有,因此除了run
之外,没有人可以调用该对象的timer.schedule
方法。如果run
方法花费的时间比指定的时间长,则很可能在完成之前再次调用run方法 - 特别是因为您已将任务的实际运行传递给UI线程。
你有两个简单的选择:
run
方法中设置一个标记,指示您正在运行,如果已设置run
则不执行任何操作。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));
}
});
}
}
答案 1 :(得分:0)
您应该将synchronized
添加到方法声明中,如下所示:
public synchronized void run()
答案 2 :(得分:0)
首先,为什么有再次调用run方法的风险?如果这是真的,那对我来说听起来就像是一种设计缺陷。 其次,代替TimerTask,您可能最好使用ScheduledExecutorService代替。这是以固定间隔执行计划任务的标准,最简单和最安全的方法。除了执行程序服务之外,您的用户代码将无法访问,您可以从中获取ScheduledFuture以获取返回值,以便您知道任务何时完成(调用get()时ScheduledFuture阻止)。 在实践中查看Java Concurrency for more ...