0

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.

Tim Sigl
  • 45
  • 1
  • 8
  • Not exactly sure what you are trying to achieve. But `synchronized void printThreadName` is redundant here, and is same as `void printThreadName`, since you are creating new objects every time. `synchronized` on a function locks on `this`. So all your threads are locking on different objects and will not block each other. – Adwait Kumar Jun 30 '18 at 09:28
  • 3
    If you want it in order why are you using threads? – user207421 Jun 30 '18 at 09:38
  • I've seen many questions here, usually homework assignments, that ask more or less the same thing, "make _somenumberof_ threads do _certainthings_ in _someorder_." The thing that the instructor never seems to tell the students is that is not what threads are for. The best way to make a program do certain things in a certain order is to do all of those things in the same thread. Threads work best when there is _minimal_ communication between them. Generally, the more your program forces them to communicate and synchronize with each other, the less benefit there is to using threads. – Solomon Slow Jun 30 '18 at 14:20
  • The goal is absolutely unrealistic. Threads are for parallel execution, while serial execution can be easily achieved on a single thread. Is it a homework? Then your teacher does not know what to teach you. – Alexei Kaigorodov Jul 01 '18 at 17:12
  • Yeah, it was a homework. The teacher explained quite well what threads are for and how to use them efficiently. Nevertheless the tasks seems quite stupid. – Tim Sigl Jul 04 '18 at 10:31

1 Answers1

2

The problem is you created multiple NameOutputs, 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
xingbin
  • 27,410
  • 9
  • 53
  • 103