组合两个 Runnable 对象
举例来说,我有一个名为 RunnableA 的 Runnable,它可以执行某些操作。我还有一个名为 RunnableB 的 Runnable,它可以执行其他操作。有没有办法可以将这两个 Runnable 组合起来,以便它们在同一个线程中运行?
问题的第二部分是如果这可能的话,我可以指定它们运行的顺序吗?
编辑!:我想这样做的原因是因为我需要在 EDT 上运行代码,但其他一些代码需要在另一个线程上运行。请看下面的代码。
像这样的事情
public final class CompoundRunnable implements Runnable
{
private final Iterable runnables;
public CompoundRunnable(Iterable runnables)
{
// From Guava. Easy enough to do by hand if necessary
this.runnables = Lists.newArrayList(runnables);
}
public CompoundRunnable(Runnable... runnables)
{
this(Arrays.asList(runnables));
}
@Override
public void run()
{
for (Runnable runnable : runnables)
{
runnable.run();
}
}
}
public void setStatusAndProgress(final String status,Runnable runnable)
{
Runnable startUpRunner = new Runnable()
{
public void run()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
setStatus(status);
selfReference.getProgressBar().setIndeterminate(true);
}
});
}
};
Runnable cleanUpRunner = new Runnable()
{
public void run()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
setStatus("");
getProgressBar().setIndeterminate(false);
}
});
}
};
Runnable theRunner = new CompoundRunnable(startUpRunner,runnable,cleanUpRunner);
new Thread(theRunner).start();
}
抱歉,如果解释得不好,如果您需要澄清,请发表评论。
谢谢!
Say for example that I have a Runnable called RunnableA that does something. I also have a Runnable called RunnableB that does something else. Is there a way that I can combine these two Runnables someway so that they will run in the same thread?
The second part of the question is if this is possible, can I then specify the order that they will run in?
EDIT!: The reason why I wanted to do this was because I need to run code on the EDT but some of the other code needs to be run on another thread. Please take a look at the code below.
Something like this
public final class CompoundRunnable implements Runnable
{
private final Iterable runnables;
public CompoundRunnable(Iterable runnables)
{
// From Guava. Easy enough to do by hand if necessary
this.runnables = Lists.newArrayList(runnables);
}
public CompoundRunnable(Runnable... runnables)
{
this(Arrays.asList(runnables));
}
@Override
public void run()
{
for (Runnable runnable : runnables)
{
runnable.run();
}
}
}
public void setStatusAndProgress(final String status,Runnable runnable)
{
Runnable startUpRunner = new Runnable()
{
public void run()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
setStatus(status);
selfReference.getProgressBar().setIndeterminate(true);
}
});
}
};
Runnable cleanUpRunner = new Runnable()
{
public void run()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
setStatus("");
getProgressBar().setIndeterminate(false);
}
});
}
};
Runnable theRunner = new CompoundRunnable(startUpRunner,runnable,cleanUpRunner);
new Thread(theRunner).start();
}
Sorry if this isnt explained well, post comments if you need clarification.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好吧,你当然可以创建一个
Runnable
,它只运行一个可运行的,然后运行另一个:更一般地,你可以让它采用一个
Iterable
,复制所有Runnable
引用,然后按顺序运行它们。例如:Well you can certainly create a
Runnable
which just runs one runnable then the other:More generally, you could make it take an
Iterable<Runnable>
, copy all theRunnable
references, and then run them in order. For example:当然。只需创建另一个可运行对象,该可运行对象调用两个现有可运行对象的运行方法作为其实现的一部分。您可以使用 Runnable 列表等来专门构建或通用包装 Runnable。
也许让您感到困惑的是 Runnable 与线程的关联。 Runnable 接口不与线程绑定,并且本身不具有任何线程语义,因此您可以像上面一样轻松地组合它,而不会以某种方式陷入线程状态的麻烦。
Sure. Just create another runnable that calls the run methods of your two existing Runnable's as part of its implementation. You can make the wrapping Runnable purpose-built or generic with a list of Runnables, etc.
Perhaps what's confusing you is association of Runnable with threads. The Runnable interface isn't tied to threads and doesn't by itself have any threading semantics, so you can easily combine it like above without somehow getting into trouble with thread states.
是的,您当然可以将它们结合起来。但一般来说,除了调用其他对象以实际完成工作之外,可运行对象内部不应该有太多内容。您能不能只获取您需要的可运行对象的“内部”并在您想要的上下文中执行它们。
如果您想确保事情只是一个接一个地执行,而不是同时执行,您可以使用 SingleThreadExecutorService 并为它们提供 Runnables。它将一次执行一个。
如果您确实想运行多个可运行对象,那么您可以这样做(第一个 RuntimeException 将退出)。
请注意静态便捷方法,因此您可以说“new Thread(CompositeRunnable.combine(a,b,c,d...))”
Yes you can of course combine them. In general though, there shouldn't be much inside a runnable except a call to some other object, to actually get the work done. Can you not just take the "insides" of the runnables you need and execute them in the context you want.
If you want to make sure things are simply executed one after the other, rather than at the same time you can use a SingleThreadExecutorService and give them the Runnables. It will execute one at a time.
If you really want to run multiple runnables then you can do it like this (the first RuntimeException will exit).
Note the static convenience method so you can say "new Thread(CompositeRunnable.combine(a,b,c,d....))"
另一种变化。
Another variation.
我很惊讶没有人提出更灵活的方法,与现有答案相比,这恰好也是最简单和最短的解决方案。
只需创建一个新类
RunList
,该类是具体List
实现之一(例如ArrayList
)的子类,然后声明它实现Runnable
code>定义该类后,您可以继续定义:
然后使用您想要运行的所有
Runnables
填充runList
。现在,您可以使用完整的 Java 语言和标准库来对列表进行重新排序或常规操作。下面包含一些示例(未经测试)用法。
I'm surprised nobody suggested the more flexible approach, which just so happens to be also the simplest and and shortest solution compared to the existing answers.
Just create a new class
RunList
that subclasses one of the concreteList
implementations (e.g.ArrayList
) and then declare it implementsRunnable
With that class defined, you can then go about defining:
And then populate
runList
with all of theRunnables
you want to run. You now have the full Java language and standard library at your disposal here for reordering or general manipulation of the list.Some example (untested) usage is included below.