How execute a thread before another?

I have a small question for you.

I have two threads:

  • HelloThread - This prints "hello" five times.
  • GoodbyeThread - This prints "Goodbye" five times.

I would like the HelloThread run first and after it's done the GoodbyeThread run.
I have already solve this problem with semaphore (but semaphore doesn't really true java way, it's more C way).

HelloThread.java

    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    package modifiedthreadhellogoodbye;

    import static java.lang.Thread.sleep;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import java.util.concurrent.Semaphore;

    class HelloThread implements Runnable {

        private final Object lock;
        //private final Semaphore lock;

        public HelloThread(Semaphore lock) {
            this.lock = lock;
        }

        public HelloThread(Object lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            int pause;
            synchronized (lock) {
                for (int i = 0; i < 5; i++) {
                    System.out.println("Hello!");
                    pause = (int) (Math.random() * 1000);
                    try {
                        sleep(pause);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(HelloThread.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                lock.notifyAll();
                System.out.println("Outsite hello");
            }
                //lock.release();

        }
    }

GoodbyeThread.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package modifiedthreadhellogoodbye;

import static java.lang.Thread.sleep;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

class GoodbyeThread implements Runnable {

    int pause;
    //private final Semaphore lock;
    private final Object lock;

    public GoodbyeThread(Semaphore lock) {
        this.lock = lock;
    }

    public GoodbyeThread(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println("Inside the synchronized");
            try {
                lock.wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(GoodbyeThread.class.getName()).log(Level.SEVERE, null, ex);
            }

            //lock.acquire();
            for (int i = 0; i < 5; i++) {
                System.out.println("Goodbye");
                pause = (int) (Math.random() * 1000);
                try {
                    sleep(pause);
                } catch (InterruptedException ex) {
                    Logger.getLogger(GoodbyeThread.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

}

and this is my class who run thread :

public class ModifiedThreadObject {

    private final Object lock = new Object();
    //private final Semaphore lock = new Semaphore(0);

    public ModifiedThreadObject() {
        HelloThread hello = new HelloThread(lock);
        GoodbyeThread goodbye = new GoodbyeThread(lock);

        Thread t1 = new Thread(hello);
        Thread t2 = new Thread(goodbye);
        t1.start();
        t2.start();
    }

}

The main idea is GoodbyeThread should wait() for the signal from HelloThread.
If GoodbyeThread is run first, it's work perfectly, but HelloThread runs first I have the following output:

Hello!
Hello!
Hello!
Hello!
Hello!
Outsite hello
Inside the synchronized

HelloThread sends a notifyAll(), but nobody is waiting so the "signal" is lost ...

Anybody have an idea?

Jon Skeet
people
quotationmark

Firstly, I'd question the use of separate threads at all here. If you want one thing to happen after another, just use a single thread.

However, it's easy to wait until one thread has finished - just use join:

Thread t1 = new Thread(hello);
Thread t2 = new Thread(goodbye);
t1.start();
t1.join();
t2.start();

That way you don't need any synchronization within the "hello" or "goodbye" code.

If you want anything more complicated, I'd recommend looking in the java.util.concurrent package. While you can use wait() and notify(), it's generally a better idea to use higher-level constructs. For example, for a producer/consumer scenario, you may well want to use BlockingQueue rather than implement it all yourself.

people

See more on this question at Stackoverflow