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.

5
  • 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. Commented Jun 30, 2018 at 9:28
  • 3
    If you want it in order why are you using threads? Commented Jun 30, 2018 at 9: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. Commented Jun 30, 2018 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. Commented Jul 1, 2018 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. Commented Jul 4, 2018 at 10:31

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.