Easier way to synchronize 2 threads in Java?

懵懂的女人 提交于 2019-12-10 14:08:45

问题


I wan't to be sure that some piece of my code within the main thread will be executed after some piece of code executed withing the secondary thread. Here's what I got:

    final Object lock = new Object();
    final Thread t = new Thread(new Runnable() {
        public void run() {
            synchronized(lock) {
                System.out.println("qwerty");
                lock.notify();
            }
        }
    });

    synchronized(lock) {
        t.start();
        lock.wait();
    }

    System.out.println("absolutely sure, qwerty is above");
  1. Is it correct solution?
  2. Any shorter ways to do the same?

回答1:


Assuming that your main thread needs to initiate the secondary thread's processing, an Exchanger would be the simplest solution.

If the secondary thread is independent, then some form of BlockingQueue would be appropriate.


An example using Exchanger (with proper exception handling). The one Exchanger could be substituted with two queues.

public static void main(String[] argv)
throws Exception
{
    final Exchanger<String> exchanger = new Exchanger<String>();
    new Thread(new Runnable() 
    {
        @Override
        public void run() 
        {
            try
            {
                String s = exchanger.exchange("");
                System.out.println(s);
                exchanger.exchange("this came from subthread");
            }
            catch (InterruptedException ex)
            {
                System.out.println("interrupted while waiting for message");
            }
        }
    }).start();

    exchanger.exchange("this came from main thread");
    String s = exchanger.exchange("");
    System.out.println(s);
}



回答2:


Things like notify() and wait() are really low-level synchronization primitives.

You should use higher-level abstractions whenever possible, like in this case, say, a CountDownLatch.

The following is just an example that should get you started (for example the timeout issues aren't taken into account here):

    final CountDownLatch latch = new CountDownLatch(1);
    final Thread t = new Thread(new Runnable() {
        public void run() {
            System.out.println("qwerty");
            latch.countDown();
        }
    });

    t.start();
    latch.await();

    System.out.println("absolutely sure, qwerty as been printed");

Low-level things like wait and notify are really just low-level Java idiosynchrasies that you shouldn't be concerned with (unless you're writing concurrency APIs).

Additionally, I'd suggest reading the amazing book: Java Concurrency In Practice.




回答3:


final Thread t = new Thread(new Runnable() {
    public void run() {
        System.out.println("qwerty");
    }
});

t.start();
t.join();

System.out.println("absolutely sure, qwerty is above");



回答4:


The best solution for the code you have given is:

System.out.println("qwerty");
System.out.println("absolutely sure, qwerty is above");

Don't use threading when you don't need it.

But if you know what you're doing with the thread, then @DoubleMalt's solution is the way to go (t.join()).

You'd also probably find it worth reading http://download.oracle.com/javase/tutorial/essential/concurrency/



来源:https://stackoverflow.com/questions/7042762/easier-way-to-synchronize-2-threads-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!