简体   繁体   English

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

[英]How to order thread completion and use join()

How can i order the completion of threads? 如何订购线程完成功能? I want the below order. 我要以下订单。

Third ---> Second --> First --> Fourth. 第三--->第二->第一->第四。

What changes should i make in code. 我应该在代码中进行哪些更改。 I am a new starter. 我是新手。 Also please elaborate about thread priority and join. 还请详细说明线程优先级和加入。 Can i call join() on two threads like thread3 waits for thread2 to complete. 我可以在两个线程上调用join(),例如线程3等待线程2完成。

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.");
    }
}

Any time you want a sequence of things to happen, one after the other, in a particular order, you'll need to use one thread to make those things happen in that order. 每当您希望一系列事情以特定顺序一个接一个地发生时,您将需要使用一个线程来使这些事情按该顺序发生。

So, say you have four threads running, and you want the four threads to terminate in a particular order. 因此,假设您有四个正在运行的线程,并且您希望这四个线程以特定顺序终止。 I don't know why you would want that, but here is how it could be done: 我不知道您为什么要这么做,但是可以这样做:

You are going to have to write each thread so that it does whatever it does, and then it waits for permission to die . 您将必须编写每个线程,以便它可以执行所有操作,然后等待权限终止

class MyTask implements Runnable {
    private final Semaphore permissionToDie = new Semaphore(0);

    public void grantPermissionToDie() {
        permissionToDie.release();
    }

    @Override
    public void run() {
        doWhatever();
        permissionToDie.acquire();
    }
}

Then, in your main thread, you will grant each thread permission to die, and then wait for it to die (ie, join() it) before granting permission to the next thread. 然后,在您的主线程中,您将授予每个线程死亡的权限,然后等待它死亡(即, join()它),然后再将权限授予下一个线程。

public void main(...) {
    MyTask tj1 = new Thread(new MyTask());
    MyTask tj2 = new Thread(new MyTask());
    MyTask tj3 = new Thread(new MyTask());
    MyTask tj4 = new Thread(new MyTask());

    tj1.start();
    tj2.start();
    tj3.start();
    tj4.start();

    ...

    t3.grantPermissionToDie();
    t3.join();

    t2.grantPermissionToDie();
    t2.join();

    t1.grantPermissionToDie();
    t1.join();

    t4.grantPermissionToDie();
    t4.join();
}

Thread priority is pretty irrelevant for finish order. 线程优先级与完成顺序无关紧要。 It can control the order if your work queue is long enough as the higher priority threads will move through the queue faster but typically if you need this kind of control you have the threads join on each other. 如果您的工作队列足够长,它可以控制顺序,因为优先级较高的线程将更快地通过队列,但是通常,如果您需要这种控制,则可以使线程彼此连接。 For example, the following snippet will always have thread one end before thread two ends. 例如,以下代码段始终在线程两端之前拥有线程一端。

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();
}

Another option is to use a wait object or condition variable. 另一种选择是使用等待对象或条件变量。

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();
}

In a real world example the naming and distribution of the condition objects may make more sense. 在现实世界中,条件对象的命名和分布可能更有意义。 For example, there might be an "initialization" phase which has to happen before worker threads start working. 例如,可能需要在工作线程开始工作之前发生“初始化”阶段。 The initializer thread would signal the completion of the initialization phase and the worker threads would wait for the signal before beginning work. 初始化程序线程将发出信号通知初始化阶段已完成,而工作线程将在开始工作之前等待该信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM