排序线程按照它们创建/启动的顺序运行
我如何按照线程实例化的顺序对线程进行排序。例如,如何使下面的程序按顺序打印数字 1...10。
public class ThreadOrdering {
public static void main(String[] args) {
class MyRunnable implements Runnable{
private final int threadnumber;
MyRunnable(int threadnumber){
this.threadnumber = threadnumber;
}
public void run() {
System.out.println(threadnumber);
}
}
for(int i=1; i<=10; i++){
new Thread(new MyRunnable(i)).start();
}
}
}
How can i order threads in the order they were instantiated.e.g. how can i make the below program print the numbers 1...10 in order.
public class ThreadOrdering {
public static void main(String[] args) {
class MyRunnable implements Runnable{
private final int threadnumber;
MyRunnable(int threadnumber){
this.threadnumber = threadnumber;
}
public void run() {
System.out.println(threadnumber);
}
}
for(int i=1; i<=10; i++){
new Thread(new MyRunnable(i)).start();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
听起来你想要
ExecutorService.invokeAll
,它将以固定顺序返回工作线程的结果,即使它们可能以任意顺序调度:Sounds like you want
ExecutorService.invokeAll
, which will return results from worker threads in a fixed order, even though they may be scheduled in arbitrary order:“我实际上有一些部分想要并行执行,然后一旦生成结果,我想按特定顺序合并结果。”谢谢,这澄清了你的问题。
您可以同时运行它们,但重要的是当线程完成计算时按顺序获取它们的结果。
Thread#join()
按照您想要获取结果的顺序排列它们,或者只是Thread#join()
它们全部然后迭代它们以获得结果。"I actually have some parts that i want to execute in parallel, and then once the results are generated, I want to merge the results in certain order." Thanks, this clarifies what you're asking.
You can run them all at once, but the important thing is to get their results in order when the threads finish their computation. Either
Thread#join()
them in the order in which you want to get their results, or justThread#join()
them all and then iterate through them to get their results.简单来说,线程的调度是不确定的。
死域 - 请勿点击http://www.janeg.ca/scjp/threads/scheduling.html
上述页面的 WaybackMachine 版本
较长的答案是如果您想执行此操作,则需要手动等待每个线程完成其工作,然后才能允许另一个线程运行。请注意,以这种方式,所有线程仍将交错,但在您允许之前它们不会完成任何工作。看一下同步保留字。
Simply put, the scheduling of threads is indeterminate.
Dead domain - do not clickhttp://www.janeg.ca/scjp/threads/scheduling.html
WaybackMachine version of the above page
The longer answer is that if you want to do this, you'll need to manually wait for each thread to complete its work before you allow another to run. Note that in this fashion, all the threads will still interleave but they won't accomplish any work until you give the go-ahead. Have a look at the synchronize reserved word.
您可以将它们链接起来 - 也就是说,让第一个启动第二个,第二个启动第三个,等等。它们不会真正同时运行,除了每个启动时有一点重叠之外。
You can chain them – that is, have the first one start the second, the second start the third, etc. They won't really be running at the same time except for a bit of overlap when each one is started.
这是一种无需等待每个结果的主线程即可完成此操作的方法。相反,让工作线程共享一个对结果进行排序的对象。
Here's a way to do it without having a master thread that waits for each result. Instead, have the worker threads share an object which orders the results.
如果您需要细粒度的控制,则不应使用线程,而应考虑将合适的 Executor 与 Callables 或 Runnables 一起使用。请参阅 Executors 类以获取广泛的选择。
If you need that fine-grained control, you should not use threads but instead look into using a suitable Executor with Callables or Runnables. See the Executors class for a wide selection.
一个简单的解决方案是使用锁数组
A
(每个线程一个锁)。当线程i
开始执行时,它会获取关联的锁A[i]
。当它准备好合并其结果时,它会释放其锁A[i]
并等待锁A[0]、A[1]、...、A[i - 1]待发布;然后它合并结果。
(在这种情况下,线程
i
表示第i
启动的线程)我不知道在Java中使用什么类,但它必须很容易实现。您可以开始阅读此。
如果您还有更多问题,请随时提问。
A simple solution would be to use an array
A
of locks (one lock per thread). When threadi
begins its executions, it acquires its associated lockA[i]
. When it's ready to merge its results, it releases its lockA[i]
and waits for locksA[0], A[1], ..., A[i - 1]
to be released; then it merges the results.(In this context, thread
i
means thei
-th launched thread)I don't know what classes to use in Java, but it must be easy to implement. You can begin reading this.
If you have more questions, feel free to ask.
使用信号量可以很容易地实现线程执行顺序的控制。所附代码基于 Schildt 关于 Java 的书(完整参考......)中提出的想法。
// 基于以下内容中提出的想法:
// Schildt H.:Java.The.Complete.Reference.9th.Edition。
Control of thread execution order may be implemented quite easily with the semaphores. The code attached is based on the ideas presented in Schildt's book on Java (The complete reference....).
// Based on the ideas presented in:
// Schildt H.: Java.The.Complete.Reference.9th.Edition.
这可以不使用synchronized关键字并在易失性关键字的帮助下完成。以下是代码。
以下是 github 链接,其中有一个自述文件,其中详细解释了它是如何发生的。
This can be done without using synchronized keyword and with the help of volatile keyword. Following is the code.
Following is the github link which has a readme, that gives detailed explanation about how it happens.
https://github.com/sankar4git/volatile_thread_ordering
如果有人需要,这是我在 Python 中解决这个问题的看法。我的方法是使用双端队列。该类的每个实例都将自己放入队列中,在构造时执行工作任务,然后等待队列的前一个成员终止其输出以完成其任务。诀窍是每个实例都有两个锁(也称为信号量)来控制打印。从队列中输入的最后一个实例复制的一个:我将等待此锁打印。另一种是在构造时创建并锁定的。进入队列的下一个实例将复制该实例,并且必须等待我释放它,我将在打印完成后执行此操作。
In case someone needs, this is my take at this problem in Python. My approach is to use a deque. Each instance of the class places itself on the queue, does the working task right at construction, then waits for the previous member of the queue to terminate its output to do his. The trick is that each instance has two locks (aka semaphores) to control printing. One which is copied from the last instance entered in the queue: I wil wait for this lock to print. Another one that is created and locked at construction. The next instance to enter the queue will copy that one and will have to wait for me to release it, which I will do after my printing is done.