我有一个小问题要问你。

我有两个线程:

  • HelloThread-这将打印“hello”五次。
  • GoodbyeThread-这将打印“再见”五次。

  • 我希望先运行HelloThread,然后再运行GoodbyeThread
    我已经用信号量解决了这个问题(但是信号量并不是真正的Java方式,它更像是C方式)。
    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);
                    }
                }
            }
        }
    
    }
    

    这是我的类(class)执行绪的人:
    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();
        }
    
    }
    

    主要思想是GoodbyeThread应该是wait(),用于来自HelloThread的信号。
    如果首先运行GoodbyeThread,则运行正常,但是首先运行HelloThread,我得到以下输出:
    Hello!
    Hello!
    Hello!
    Hello!
    Hello!
    Outsite hello
    Inside the synchronized
    
    HelloThread发送notifyAll(),但是没有人在等待,因此“信号”丢失了...

    有人有主意吗?

    最佳答案

    首先,我会在这里质疑单独线程的使用。如果您希望一件事情接连发生,只需使用一个线程即可。

    但是,很容易等到一个线程结束-只需使用join即可:

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

    这样,您无需在“hello”或“再见”代码内进行任何同步。

    如果您想要更复杂的内容,建议您查看java.util.concurrent包。虽然可以使用wait()notify(),但是通常最好使用更高级别的构造。例如,对于生产者/消费者方案,您可能要使用 BlockingQueue 而不是自己全部实现。

    10-07 16:57