简体   繁体   中英

Java Threads - Call threads in order

I want the threads to print out their name in order. The ouput should look something like this: Thread-0
Thread-1
Thread-2
Thread-3
Thread-4
Thread-5
Thread-1
Thread-2
Thread-3

public class NameOutput extends Thread {
    static final int N = 5;
    static int activeThread = 0;

    public static void main(String[] args){

        for (int i = 1; i <= N; i++) {
            new NameOutput().start();
        }
    }

    @Override
    public void run(){
        while(true){
            this.printThreadName();
        }

    }
    private synchronized void printThreadName(){
        String threadName = "Thread-"+ activeThread;
        //Check if thread is in the right order
        if(!threadName.equals(this.getName())){
            try{
                wait();
            }catch (InterruptedException e){
                System.out.println(this.getName()+" was interrupted!");
            }
        }else{
            System.out.println(this.getName());
            activeThread = (activeThread + 1) % N;
            notifyAll();
        }
    }
}

Somehow the output is if Thread-0 gets selected first just Thread-0. The programm stops after the first thread waits.

The problem is you created multiple NameOutput s, and they use their own monitor lock , which means there will be no 'communication'(signal) between them.

Instead, you need a shared monitor lock:

public class NameOutput extends Thread {
    static final int N = 5;
    static int activeThread = 0;
    static final Object lock = new Object(); // shared monitor lock

    public static void main(String[] args){

        for (int i = 1; i <= N; i++) {
            new NameOutput().start();
        }
    }

    @Override
    public void run(){
        while(true){
            this.printThreadName();
        }

    }
    private void printThreadName(){
        synchronized (lock) {
            String threadName = "Thread-"+ activeThread;
            //Check if thread is in the right order
            if(!threadName.equals(this.getName())){
                try{
                    lock.wait();
                }catch (InterruptedException e){
                    System.out.println(this.getName()+" was interrupted!");
                }
            }else{
                System.out.println(this.getName());
                activeThread = (activeThread + 1) % N;
                lock.notifyAll();
            }
        }
    }
}

Another problem, wait should always be used in while loop, you can do a little more:

private void printThreadName(){
    synchronized (lock) {
        while (!("Thread-"+ activeThread).equals(this.getName())) {
            try{
                lock.wait();
            }catch (InterruptedException e){
                System.out.println(this.getName()+" was interrupted!");
            }
        }
        System.out.println(this.getName());
        activeThread = (activeThread + 1) % N;
        lock.notifyAll();
    }
}

output:

Thread-0
Thread-1
Thread-2
Thread-3
Thread-4
Thread-0
Thread-1
Thread-2
Thread-3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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