How to make a Java thread wait for another thread&

2019-01-01 04:40发布

I'm making a Java application with an application-logic-thread and a database-access-thread. Both of them persist for the entire lifetime of the application and both need to be running at the same time (one talks to the server, one talks to the user; when the app is fully started, I need both of them to work).

However, on startup, I need to make sure that initially the app thread waits until the db thread is ready (currently determined by polling a custom method dbthread.isReady()). I wouldn't mind if app thread blocks until the db thread was ready.

Thread.join() doesn't look like a solution - the db thread only exits at app shutdown.

while (!dbthread.isReady()) {} kind of works, but the empty loop consumes a lot of processor cycles.

Any other ideas? Thanks.

13条回答
墨雨无痕
2楼-- · 2019-01-01 05:08

If you want something quick and dirty, you can just add a Thread.sleep() call within your while loop. If the database library is something you can't change, then there is really no other easy solution. Polling the database until is ready with a wait period won't kill the performance.

while (!dbthread.isReady()) {
  Thread.sleep(250);
}

Hardly something that you could call elegant code, but gets the work done.

In case you can modify the database code, then using a mutex as proposed in other answers is better.

查看更多
高级女魔头
3楼-- · 2019-01-01 05:13

You could do it using an Exchanger object shared between the two threads:

private Exchanger<String> myDataExchanger = new Exchanger<String>();

// Wait for thread's output
String data;
try {
  data = myDataExchanger.exchange("");
} catch (InterruptedException e1) {
  // Handle Exceptions
}

And in the second thread:

try {
    myDataExchanger.exchange(data)
} catch (InterruptedException e) {

}

As others have said, do not take this light-hearted and just copy-paste code. Do some reading first.

查看更多
临风纵饮
4楼-- · 2019-01-01 05:14

Use a CountDownLatch with a counter of 1.

CountDownLatch latch = new CountDownLatch(1);

Now in the app thread do-

latch.await();

In the db thread, after you are done, do -

latch.countDown();
查看更多
皆成旧梦
5楼-- · 2019-01-01 05:17

enter image description here

This idea can apply?. If you use CountdownLatches or Semaphores works perfect but if u are looking for the easiest answer for an interview i think this can apply.

查看更多
不流泪的眼
6楼-- · 2019-01-01 05:18

Requirement ::

  1. To wait execution of next thread until previous finished.
  2. Next thread must not start until previous thread stops, irrespective of time consumption.
  3. It must be simple and easy to use.

Answer ::

@See java.util.concurrent.Future.get() doc.

future.get() Waits if necessary for the computation to complete, and then retrieves its result.

Job Done!! See example below

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.junit.Test;

public class ThreadTest {

    public void print(String m) {
        System.out.println(m);
    }

    public class One implements Callable<Integer> {

        public Integer call() throws Exception {
            print("One...");
            Thread.sleep(6000);
            print("One!!");
            return 100;
        }
    }

    public class Two implements Callable<String> {

        public String call() throws Exception {
            print("Two...");
            Thread.sleep(1000);
            print("Two!!");
            return "Done";
        }
    }

    public class Three implements Callable<Boolean> {

        public Boolean call() throws Exception {
            print("Three...");
            Thread.sleep(2000);
            print("Three!!");
            return true;
        }
    }

    /**
     * @See java.util.concurrent.Future.get() doc
     *      <p>
     *      Waits if necessary for the computation to complete, and then
     *      retrieves its result.
     */
    @Test
    public void poolRun() throws InterruptedException, ExecutionException {
        int n = 3;
        // Build a fixed number of thread pool
        ExecutorService pool = Executors.newFixedThreadPool(n);
        // Wait until One finishes it's task.
        pool.submit(new One()).get();
        // Wait until Two finishes it's task.
        pool.submit(new Two()).get();
        // Wait until Three finishes it's task.
        pool.submit(new Three()).get();
        pool.shutdown();
    }
}

Output of this program ::

One...
One!!
Two...
Two!!
Three...
Three!!

You can see that takes 6sec before finishing its task which is greater than other thread. So Future.get() waits until the task is done.

If you don't use future.get() it doesn't wait to finish and executes based time consumption.

Good Luck with Java concurrency.

查看更多
冷夜・残月
7楼-- · 2019-01-01 05:18

A lot of correct answers but without a simple example.. Here is an easy and simple way of to use CountDownLatch:

//inside your currentThread.. lets call it Thread_Main
//1
final CountDownLatch latch = new CountDownLatch(1);

//2
// launch thread#2
new Thread(new Runnable() {
    @Override
    public void run() {
        //4
        //do your logic here in thread#2

        //then release the lock
        //5
        latch.countDown();
    }
}).start();

try {
    //3 this method will block the thread of latch untill its released later from thread#2
    latch.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}

//6
// You reach here after  latch.countDown() is called from thread#2
查看更多
登录 后发表回答