Java线程-按顺序调用线程

时间:2018-06-30 09:08:09

标签: java multithreading

我希望线程按顺序打印出它们的名称。输出应如下所示: 线程-0
线程1
线程2
线程3
线程4
线程5
线程1
线程2
线程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();
        }
    }
}

不知何故,如果首先选择Thread-0,那么输出就是Thread-0。在第一个线程等待之后,程序将停止。

1 个答案:

答案 0 :(得分:2)

问题是您创建了多个NameOutput,并且它们使用their own 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();
            }
        }
    }
}

另一个问题,wait should总是在while循环中使用,您可以做更多的事情:

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

输出:

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