Java 排序线程以其创建/启动的顺序运行

Java 排序线程以其创建/启动的顺序运行,java,multithreading,synchronization,Java,Multithreading,Synchronization,我如何按照线程被实例化的顺序排列线程。如何使下面的程序按顺序打印数字1…10 public class ThreadOrdering { public static void main(String[] args) { class MyRunnable implements Runnable{ private final int threadnumber; MyRunnable(int threadnumber){

我如何按照线程被实例化的顺序排列线程。如何使下面的程序按顺序打印数字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();
        }
    }
}
公共类线程排序{
公共静态void main(字符串[]args){
类MyRunnable实现Runnable{
私有最终整数线程数;
MyRunnable(int threadnumber){
this.threadnumber=threadnumber;
}
公开募捐{
System.out.println(螺纹编号);
}
}

简单地说,对于(inti=1;i,线程的调度是不确定的

http://www.janeg.ca/scjp/threads/scheduling.html
死域-不要单击


较长的答案是,如果要执行此操作,您需要手动等待每个线程完成其工作,然后再允许另一个线程运行。请注意,以这种方式,所有线程仍将交错,但在您允许之前,它们不会完成任何工作。请查看同步保留字。

如果需要的话细粒度控制,您不应该使用线程,而是应该考虑使用具有可调用或可运行的合适的执行器。请参阅Executors类以获得广泛的选择。

您可以链接它们–也就是说,让第一个启动第二个,第二个启动第三个,等等。它们不会真正同时运行,除非有一点每次启动时重叠

public class ThreadOrdering
{
    public static void main(String[] args)
    {
        MyRunnable[] threads = new MyRunnable[10];//index 0 represents thread 1;
        for(int i=1; i<=10; i++)
            threads[i] = new MyRunnable(i, threads); 
        new Thread(threads[0].start);  
    }
}

public class MyRunnable extends Runnable
{
    int threadNumber;
    MyRunnable[] threads;

    public MyRunnable(int threadNumber, MyRunnable[] threads)
    {
        this.threadnumber = threadnumber;
        this.threads = threads;
    }

    public void run()
    {
        System.out.println(threadnumber);
        if(threadnumber!=10)
            new Thread(threadnumber).start();
    }
}
公共类线程排序
{
公共静态void main(字符串[]args)
{
MyRunnable[]threads=new MyRunnable[10];//索引0表示线程1;
对于(int i=1;i“实际上,我有一些部分需要并行执行,然后在生成结果后,我希望按一定顺序合并结果。”谢谢,这澄清了您的问题

您可以一次运行所有线程,但重要的是在线程完成计算时按顺序获得它们的结果。可以按您希望的顺序获得它们的结果,也可以将它们全部运行,然后迭代以获得它们的结果

// Joins the threads back to the main thread in the order we want their results.
public class ThreadOrdering {
    private class MyWorker extends Thread {
        final int input;
        int result;
        MyWorker(final int input) {
            this.input = input;
        }
        @Override
        public void run() {
            this.result = input; // Or some other computation.
        }
        int getResult() { return result; }
    }

    public static void main(String[] args) throws InterruptedException {
        MyWorker[] workers = new MyWorker[10];
        for(int i=1; i<=10; i++) {
            workers[i] = new MyWorker(i);
            workers[i].start();
        }

        // Assume it may take a while to do the real computation in the threads.

        for (MyWorker worker : workers) {
            // This can throw InterruptedException, but we're just passing that.
            worker.join();
            System.out.println(worker.getResult());
        }
    }
}
//按照我们想要的结果顺序将线程连接回主线程。
公共类线程排序{
私有类MyWorker扩展线程{
最终整数输入;
int结果;
MyWorker(最终整数输入){
这个输入=输入;
}
@凌驾
公开募捐{
this.result=input;//或其他一些计算。
}
int getResult(){return result;}
}
公共静态void main(字符串[]args)引发InterruptedException{
MyWorker[]工人=新的MyWorker[10];

对于(inti=1;i来说,一个简单的解决方案是使用一个锁数组
A
(每个线程一个锁)。当线程
i
开始执行时,它获取相关的锁
A[i]
。当它准备合并结果时,它释放锁
A[i]
,并等待锁
A[0],A[1],…,A[i-1]
发布;然后合并结果

import java.util.*;

public class OrderThreads {
    public static void main(String... args) {
        Results results = new Results();
        new Thread(new Task(0, "red", results)).start();
        new Thread(new Task(1, "orange", results)).start();
        new Thread(new Task(2, "yellow", results)).start();
        new Thread(new Task(3, "green", results)).start();
        new Thread(new Task(4, "blue", results)).start();
        new Thread(new Task(5, "indigo", results)).start();
        new Thread(new Task(6, "violet", results)).start();
    }
}

class Results {
    private List<String> results = new ArrayList<String>();
    private int i = 0;

    public synchronized void submit(int order, String result) {
        while (results.size() <= order) results.add(null);
        results.set(order, result);
        while ((i < results.size()) && (results.get(i) != null)) {
            System.out.println("result delivered: " + i + " " + results.get(i));
            ++i;
        }
    }
}


class Task implements Runnable {
    private final int order;
    private final String result;
    private final Results results;

    public Task(int order, String result, Results results) {
        this.order = order;
        this.result = result;
        this.results = results;
    }

    public void run() {
        try {
            Thread.sleep(Math.abs(result.hashCode() % 1000)); // simulate a long-running computation
        }
        catch (InterruptedException e) {} // you'd want to think about what to do if interrupted
        System.out.println("task finished: " + order + " " + result);
        results.submit(order, result);
    }
}
(在此上下文中,线程
i
表示
i
-第个启动的线程)

我不知道在Java中使用什么类,但它必须易于实现。您可以开始阅读


如果您还有更多问题,请随时提问。

听起来像您想要的
,它将以固定顺序返回工作线程的结果,即使它们可能以任意顺序安排:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ThreadOrdering {

    static int NUM_THREADS = 10;

    public static void main(String[] args) {
        ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
        class MyCallable implements Callable<Integer> {
            private final int threadnumber;

            MyCallable(int threadnumber){
                this.threadnumber = threadnumber;
            }

            public Integer call() {
                System.out.println("Running thread #" + threadnumber);
                return threadnumber;
            }
        }

        List<Callable<Integer>> callables =
            new ArrayList<Callable<Integer>>();
        for(int i=1; i<=NUM_THREADS; i++) {
            callables.add(new MyCallable(i));
        }
        try {
            List<Future<Integer>> results =
                exec.invokeAll(callables);
            for(Future<Integer> result: results) {
                System.out.println("Got result of thread #" + result.get());
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (ExecutionException ex) {
            ex.printStackTrace();
        } finally {
            exec.shutdownNow();
        }
    }

}
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
公共类线程排序{
静态int NUM_线程=10;
公共静态void main(字符串[]args){
ExecutorService exec=Executors.newFixedThreadPool(NUM_线程);
类MyCallable实现了Callable{
私有最终整数线程数;
MyCallable(int threadnumber){
this.threadnumber=threadnumber;
}
公共整数调用(){
System.out.println(“运行线程#”+线程编号);
返回线程数;
}
}
列出可调用项=
新的ArrayList();

对于(inti=1;i,这里有一种方法可以在没有主线程等待每个结果的情况下执行此操作。相反,让工作线程共享一个对结果排序的对象

import java.util.*;

public class OrderThreads {
    public static void main(String... args) {
        Results results = new Results();
        new Thread(new Task(0, "red", results)).start();
        new Thread(new Task(1, "orange", results)).start();
        new Thread(new Task(2, "yellow", results)).start();
        new Thread(new Task(3, "green", results)).start();
        new Thread(new Task(4, "blue", results)).start();
        new Thread(new Task(5, "indigo", results)).start();
        new Thread(new Task(6, "violet", results)).start();
    }
}

class Results {
    private List<String> results = new ArrayList<String>();
    private int i = 0;

    public synchronized void submit(int order, String result) {
        while (results.size() <= order) results.add(null);
        results.set(order, result);
        while ((i < results.size()) && (results.get(i) != null)) {
            System.out.println("result delivered: " + i + " " + results.get(i));
            ++i;
        }
    }
}


class Task implements Runnable {
    private final int order;
    private final String result;
    private final Results results;

    public Task(int order, String result, Results results) {
        this.order = order;
        this.result = result;
        this.results = results;
    }

    public void run() {
        try {
            Thread.sleep(Math.abs(result.hashCode() % 1000)); // simulate a long-running computation
        }
        catch (InterruptedException e) {} // you'd want to think about what to do if interrupted
        System.out.println("task finished: " + order + " " + result);
        results.submit(order, result);
    }
}
import java.util.*;
公共类OrderThreads{
公共静态void main(字符串…参数){
结果=新结果();
新线程(新任务(0,“红色”,结果)).start();
新线程(新任务(1,“橙色”,结果)).start();
新线程(新任务(2,“黄色”,结果)).start();
新线程(新任务(3,“绿色”,结果)).start();
新线程(新任务(4,“蓝色”,结果)).start();
新线程(新任务(5,“indigo”,结果)).start();
新线程(新任务(6,“紫色”,结果)).start();
}
}
课堂成绩{
私有列表结果=新建ArrayList();
私有整数i=0;
公共同步作废提交(整数顺序、字符串结果){

while(results.size()使用信号量可以很容易地实现线程执行顺序的控制。所附代码基于Schildt的Java书(完整参考…)中提出的思想。 //基于以下内容中提出的想法: //Schildt H.:Java.The.Complete.Reference.9th.Edition

import java.util.concurrent.Semaphore;

class Manager {
    int n;
// Initially red on semaphores 2&3; green semaphore 1.
    static Semaphore SemFirst = new Semaphore(1);
    static Semaphore SemSecond = new Semaphore(0);
    static Semaphore SemThird = new Semaphore(0);

void firstAction () {
    try {
        SemFirst.acquire();
    } catch(InterruptedException e) {
        System.out.println("Exception InterruptedException catched");
    }
    System.out.println("First: " );
    System.out.println("-----> 111");
    SemSecond.release();
}
void secondAction() {
    try{
        SemSecond.acquire();
    } catch(InterruptedException e) {
        System.out.println("Exception InterruptedException catched");
    }
    System.out.println("Second: ");
    System.out.println("-----> 222");
    SemThird.release();
}
void thirdAction() {
    try{
        SemThird.acquire();
    } catch(InterruptedException e) {
        System.out.println("Exception InterruptedException catched");
    }
    System.out.println("Third: ");
    System.out.println("-----> 333");
    SemFirst.release();
}
}

class Thread1 implements Runnable {
    Manager q;

    Thread1(Manager q) {
    this.q = q;
    new Thread(this, "Thread1").start();
}

public void run() {
    q.firstAction();
}
}

class Thread2 implements Runnable {
    Manager q;

    Thread2(Manager q) {
    this.q = q;
    new Thread(this, "Thread2").start();
}

public void run() {
    q.secondAction();
}
}

class Thread3 implements Runnable {
    Manager q;

    Thread3(Manager q) {
    this.q = q;
    new Thread(this, "Thread3").start();
}

public void run() {
    q.thirdAction();
}
}

class ThreadOrder {
    public static void main(String args[]) {
    Manager q = new Manager();
    new Thread3(q);
    new Thread2(q);
    new Thread1(q);
    }
}

这可以完成,而无需使用synchronized关键字,也可以借助volatile关键字。下面是代码

package threadOrderingVolatile;

public class Solution {
    static volatile int counter = 0;
    static int print = 1;
    static char c = 'A';

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Thread[] ths = new Thread[4];
        for (int i = 0; i < ths.length; i++) {
            ths[i] = new Thread(new MyRunnable(i, ths.length));
            ths[i].start();
        }
    }

    static class MyRunnable implements Runnable {
        final int thID;
        final int total;

        public MyRunnable(int id, int total) {
            thID = id;
            this.total = total;
        }

        @Override
        public void run() {
            while(true) {
                if (thID == (counter%total)) {
                    System.out.println("thread " + thID + " prints " + c);
                    if(c=='Z'){
                        c='A';
                    }else{
                        c=(char)((int)c+1);
                    }
                    System.out.println("thread " + thID + " prints " + print++);
                    counter++;                  
                } else {
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                        // log it
                    }
                }
            }
        }

    }

}
package-threadOrderingVolatile;
公共类解决方案{
静态易失性int计数器=0;
静态整型打印=1;
静态字符c='A';
公共静态void main(字符串[]args){