如何订购线程完成并使用join()

时间:2015-12-20 08:29:52

标签: java multithreading

我如何订购线程的完成?我想要下面的订单。

第三--->第二 - >首先 - >第四。

我应该在代码中做出哪些更改。我是新手。另请详细说明线程优先级和加入。我可以在两个线程上调用join(),如thread3等待thread2完成。

class TJoin implements Runnable {
Thread tj;
String tname;
int tint, tloop;
public TJoin(String name, int time, int loop) {
    tj = new Thread(this, name);
    tint = time;
    tloop = loop;
    tj.start();
    }

    public void run() {
        System.out.println("\n\t\t\t\t" + tj.getName() + " starts now.");
        for (int j = 0; j < tloop; j++) {
            System.out.println("\n" + tj.getName() + " running.");
            try {
                Thread.sleep(tint * 1000);
               } catch (InterruptedException e) {
                e.getMessage();
            }
        }
    System.out.println("\n\t\t\t\t" + tj.getName() + " ends now.");
    }
}

public class ThreadJoin {
    public static void main(String[] args) {
        System.out.println("\n\t\t\t\t" + Thread.currentThread().getName().toUpperCase() + " starts now.");
        TJoin tj1 = new TJoin("First", 1, 15);
        tj1.tj.setPriority(Thread.NORM_PRIORITY + 1);
        TJoin tj2 = new TJoin("Second", 1, 15);
        tj2.tj.setPriority(Thread.NORM_PRIORITY);
        TJoin tj3 = new TJoin("Third", 1, 15);
        tj3.tj.setPriority(Thread.MIN_PRIORITY);
        TJoin tj4 = new TJoin("Fourth", 1, 15);
        tj4.tj.setPriority(Thread.MAX_PRIORITY);

        for (int j = 0; j < 5; j++) {
            System.out.println("\n" + Thread.currentThread().getName() + " running.");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.getMessage();
            }
        }
        try {
            tj2.tj.join();
            tj3.tj.join();
            tj1.tj.join();
            tj4.tj.join();
        } catch (InterruptedException e) {
            e.getMessage();
        }
        System.out.println("\n\t\t\t\tMAIN thread ends now.");
    }
}

1 个答案:

答案 0 :(得分:0)

线程优先级与完成订单无关。如果您的工作队列足够长,它可以控制顺序,因为较高优先级的线程将更快地通过队列,但通常如果您需要这种控制,则让线程相互连接。例如,以下代码片段在第二个线程结束之前总是有一个线程结束。

public static class JoinTask implements Runnable {
    private Thread threadToWaitOn;

    public JoinTask(Thread threadToWaitOn) {
        this.threadToWaitOn = threadToWaitOn;
    }

    public void run() {
        while(thereIsWork()) {
            doWork();
        }
        if(threadToWaitOn != null) {
            threadToWaitOn.join();
        }
    }
}

public static void main(String [] args) {
     Thread threadOne = new Thread(new JoinTask(null));
     Thread threadTwo = new Thread(new JoinTask(threadOne));

     threadTwo.join();
}

另一种选择是使用等待对象或条件变量。

public static class MyCondition {
    private boolean conditionMet;

    public synchronized void markConditionMet() {
        conditionMet = true;
        notifyAll();
    }

    public synchronized void waitOnCondition() {
        while(!conditionMet) {
            wait();
        }
    }
}

public static class JoinTask implements Runnable {
    private MyCondition onExitSignalThis;
    private MyCondition onExitWaitOnThis;

    public JoinTask(MyCondition onExitSignalThis, MyCondition onExitWaitOnThis) {
        this.onExitWaitOnThis = onExitWaitOnThis;
        this.onExitSignalThis = onExitSignalThis;
    }

    public void run() {
        while(thereIsWork()) {
            doWork();
        }
        if(onExitWaitOnThis != null) {
            onExitWaitOnThis.waitOnCondition();
        }
        if(onExitSignalThis != null) {
            onExitSignalThis.markConditionMet();
        }
    }
}

public static void main(String [] args) {
     MyCondition condition;
     Thread threadOne = new Thread(condition, null);
     Thread threadTwo = new Thread(null, condition);

     threadTwo.join();
}

在现实世界的例子中,条件对象的命名和分配可能更有意义。例如,可能存在必须在工作线程开始工作之前发生的“初始化”阶段。初始化程序线程将发出初始化阶段的完成信号,工作线程将在开始工作之前等待信号。