Run functions concurrently in java with wait [duplicate] - java

During the course of my program execution, a number of threads are started. The amount of threads varies depending on user defined settings, but they are all executing the same method with different variables.
In some situations, a clean up is required mid execution, part of this is stopping all the threads, I don't want them to stop immediately though, I just set a variable that they check for that terminates them. The problem is that it can be up to 1/2 second before the thread stops. However, I need to be sure that all threads have stopped before the clean up can continues. The cleanup is executed from another thread so technically I need this thread to wait for the other threads to finish.
I have thought of several ways of doing this, but they all seem to be overly complex. I was hoping there would be some method that can wait for a group of threads to complete. Does anything like this exist?

Just join them one by one:
for (Thread thread : threads) {
thread.join();
}
(You'll need to do something with InterruptedException, and you may well want to provide a time-out in case things go wrong, but that's the basic idea...)

If you are using java 1.5 or higher, you can try CyclicBarrier. You can pass the cleanup operation as its constructor parameter, and just call barrier.await() on all threads when there is a need for cleanup.

Have you seen the Executor classes in java.util.concurrent? You could run your threads through an ExecutorService. It gives you a single object you can use to cancel the threads or wait for them to complete.

Define a utility method (or methods) yourself:
public static waitFor(Collection<? extends Thread) c) throws InterruptedException {
for(Thread t : c) t.join();
}
Or you may have an array
public static waitFor(Thread[] ts) throws InterruptedException {
waitFor(Arrays.asList(ts));
}
Alternatively you could look at using a CyclicBarrier in the java.util.concurrent library to implement an arbitrary rendezvous point between multiple threads.

If you control the creation of the Threads (submission to an ExecutorService) then it appears you can use an ExecutorCompletionService
see ExecutorCompletionService? Why do need one if we have invokeAll? for various answers there.
If you don't control thread creation, here is an approach that allows you to join the threads "one by one as they finish" (and know which one finishes first, etc.), inspired by the ruby ThreadWait class.
Basically by newing up "watching threads" which alert when the other threads terminate, you can know when the "next" thread out of many terminates.
You'd use it something like this:
JoinThreads join = new JoinThreads(threads);
for(int i = 0; i < threads.size(); i++) {
Thread justJoined = join.joinNextThread();
System.out.println("Done with a thread, just joined=" + justJoined);
}
And the source:
public static class JoinThreads {
java.util.concurrent.LinkedBlockingQueue<Thread> doneThreads =
new LinkedBlockingQueue<Thread>();
public JoinThreads(List<Thread> threads) {
for(Thread t : threads) {
final Thread joinThis = t;
new Thread(new Runnable() {
#Override
public void run() {
try {
joinThis.join();
doneThreads.add(joinThis);
}
catch (InterruptedException e) {
// "should" never get here, since we control this thread and don't call interrupt on it
}
}
}).start();
}
}
Thread joinNextThread() throws InterruptedException {
return doneThreads.take();
}
}
The nice part of this is that it works with generic Java threads, without modification, any thread can be joined. The caveat is it requires some extra thread creation. Also this particular implementation "leaves threads behind" if you don't call joinNextThread() the full number of times, and doesn't have an "close" method, etc. Comment here if you'd like a more polished version created. You could also use this same type of pattern with "Futures" instead of Thread objects, etc.

Related

How does a synchronized method work in Java?

I need a method that will run only once from the background no matter how many threads call it.
I found a partial solution using this code
my code:
public static void async(final int a){
Thread th = new Thread(new Runnable() {
#Override
public void run() {
meth(a);
}
});
th.start();
}
public static synchronized void meth(final int a){
try {
Thread.sleep(1000);
System.out.println(a);
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
But when I test it like that:
System.out.println("start");
async(11);
async(12);
async(13);
async(14);
async(15);
async(16);
async(17);
async(18);
async(19);
System.out.println("end");
I got those results:
start
end
11
19
18
17
15
16
14
13
12
Is there anything wrong with my code?
Why the results are not in the same order as the call?
edited
after using Thread.join
public static Object obg = new Object();
public static void async(final int a){
Thread th = new Thread(new Runnable() {
#Override
public void run() {
meth(a);
}
});
th.start();
try {
th.join();
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static synchronized void meth(final int a){
try {
Thread.sleep(1000);
System.out.println(a);
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
i got this result which cancled the background work :
start
11
12
13
14
15
16
17
18
19
end
Thread.join didn't gave me the results I wish
edit for the third time to give example from other languages.
I tried the same code in c#
static void Main(string[] args)
{
Console.WriteLine("start");
async(11);
async(12);
async(13);
async(14);
async(15);
async(16);
async(17);
async(18);
Console.WriteLine("end");
}
static Object o = new Object();
public static void async(int a){
new Thread(() =>
{
lock (o)
{
Thread.Sleep(1000);
Console.WriteLine(a);
}
}).Start();
}
the results was in the same order
test results from swift language are the same as c#
so my question is : how to achieve those results in java
edit :
results of using the newly created thread in the join
code :
public static void main(String[] args) throws Exception {
System.out.println("start");
async(19,async(18,async(17,async(16,async(15,async(14,async(13,async(12,async(11,null)))))))));
System.out.println("end");
}
public static Object obg = new Object();
public static Thread async(final int a,final Thread other){
Thread th = new Thread(new Runnable() {
#Override
public void run() {
meth(a);
}
});
th.start();
try {
if(other!=null){
other.join();
}
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
return th;
}
public static synchronized void meth(final int a){
try {
Thread.sleep(1000);
System.out.println(a);
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
results :
start
11
12
13
14
15
16
17
18
end
19
background work was also canceled.
Your main thread starts nine others, giving each child thread a different a, and the first thing that all nine of those child threads do is sleep for one second.
The timing resolution in the Thread.sleep() call is undefined---It depends on the underlying operating system---and it's quite possible that all of the threads were elgible to wake up on the same tick of the system clock.
Java makes no guarantee that the threads will start running in the order that their Thread objects were start()ed, and it makes no guarantee that they will wake up in the order in which they went to sleep.
Any time you want things to happen in a certain order, the best way to make that happen is to do all of the things in a single thread.
I need this section to run sequentially...I don't want it to run twice or more at the same time...I still want it to run in the background.
OK., I get it now.
You probably want to use java.util.concurrent.Executors.newSingleThreadExecutor(). That function will return a thread pool with a single worker thread.
The worker thread will run tasks that you submit to the pool "in the background", and it will run them, one at a time, in the order that they were submitted.
static final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
public static void async(final int a) {
singleThreadExecutor.submit(new Runnable() {
#Override
public void run() {
meth(a);
}
});
}
You appear to have two different questions here. You start by saying that you "need a method that will run only once from the background, no matter how many threads call it," which is one issue, and then you go on to say that the results from the different threads do not happen in the order that you want.
Question #1: Making the method run only once
You did not specify what exactly you mean by "run only once no matter how many threads call it." When it comes to multi-threaded programming, there are a few different common things that could be meant by that.Because of the example code you supplied, I will assume that you mean you want only one one at a time, but that you do want multiple calls to the method.
For this question, you are on the right track. If you have some data or action that you want to only be accessible to one thread at a time, the correct way to do that is to use a lock, also known as a mutex. In Java, this is done by creating an object to serve as a lock. The object can be of any class type - that part is not important. The important part is that all threads which need to have mutually exclusive access to some data or action all use the same instance of the locking object. A lock must be obtained on the object before the data or action is accessed, then it must be released after.
Now, with that theory part out of the way, the "synchronized" keyword you have applied to your method is more easily explained. When you apply synchronized to a Java method, what happens is that the "this" object, the one that "owns" the method (in your case, whichever object instance owns the call to meth(int)), is the object used as a lock. A lock is obtained on this before the body of the method is executed, and the lock is released after the body of the method is finished executing. This allows only one thread to access that code at a time.
Remember, though, that the different threads need to have the same instance of the lock object. If you have more than one object of whatever type you have there, then the different instances of the object can have their synchronized methods running concurrently with each other because they have separate locks.
This is probably more than sufficient to answer that part of this question, considering you were already using synchronized. For further reading, see the link I will supply at the bottom.
Question #2: Why are these threads happening out of order?
This question has a quick and easy answer: if you do not specifically do something to cause it to be otherwise, then no guarantee is ever made that the threads will ever happen in any specific order. It is as simple as that.
In your case, each thread sleeps for a second as the first thing it does, but that happens as part of that thread's action. Basically, all of your threads are all sleeping for a second at basically the same time, and then the second is up for all of them as basically the same time. And no guarantee is made about what order they will execute in.
If you had made it sleep in between instantiations of the new threads, then you probably would have caused the execution to be in the order you expected. That is, async(1); sleep; async(2); sleep; async(3); etc.. probably would have given you results more like what you seem to have been expecting, though that would sleep between every call to async and so would take a long time to finish everything. However, please note, this is not the way you should accomplish what you are looking for. Although you would probably get the output in the order you want if you sleep between calls to async, you are not guaranteed to get that order even then. For example, if your system is bogged down by other activities, it might throw off the timing such that one call to meth takes more than two seconds, so you have multiple threads waiting on the lock, and you once again get the results out of order.
Without direct intervention of some type, you are never guaranteed a thread execution order. If T1 and T2 are both executed or both waiting on a join or for whatever reason want to run, you never know which one will happen first. Usually there's no need to know.
If you need to force your threads to happen in a certain order - something which you generally want to try to avoid in order to maximize the liveness of your threads, but which sometimes is necessary - then try to take a look at some of the special Java concurrency objects which help get the timing that you might want. You can find some of them at the link I will provide below.
In the very specific case that you are supplying to us, if you just want a linear order (or even a tree-like order) where you have a set of threads {T1, T2, ..., Tn} you could use join, as you were starting to do (you were close again!), but make each thread join the one before it instead of all joining one thread. That is, have T2 join T1, T3 join T2, and so on. You can get linear execution this way, and you can also get a tree-like pattern: if you just care that T3 and T4 happen after T2 but you don't care which goes first between T3 and T4 then they can both join T2 - do this where you can to increase liveness.
If your end-goal is exactly like your question here where they are all executed linearly, you might be better off doing it in one single thread but having a list of actions that one thread needs to take, then that one thread can execute these things in order, each time it does all the actions and there's none left it then waits for more. This paragraph does not answer your question, but it's a suggestion about another way to do it, which may or may not be better depending on your use case.
And the link I mentioned...
Java Concurrency Trail
(edit: Sorry I botched the link the first time. Fixed.)
Check out that resource thoroughly. Notice the table of contents there to help you navigate around the sub-topics of Java concurrency. Some of the examples there might be difficult to grasp at first, but you seem to be going in the right direction. Keep at it.

Why did the definers of the Java Language Specification decide not to allow a Java Thread to restart? [duplicate]

I know that it is not possible to restart a used Java Thread object, but I don't find an explanation why this is not allowed; even if it is guaranteed that the thread has finished (see example code below).
I don't see why start() (or at least a restart()) method should not be able to somehow reset the internal states - whatever they are - of a Thread object to the same values they have when the Thread object is freshly created.
Example code:
class ThreadExample {
public static void main(String[] args){
Thread myThread = new Thread(){
public void run() {
for(int i=0; i<3; i++) {
try{ sleep(100); }catch(InterruptedException ie){}
System.out.print(i+", ");
}
System.out.println("done.");
}
};
myThread.start();
try{ Thread.sleep(500); }catch(InterruptedException ie){}
System.out.println("Now myThread.run() should be done.");
myThread.start(); // <-- causes java.lang.IllegalThreadStateException
} // main
} // class
I know that it is not possible to
restart a used Java Thread object, but
I don't find an explanation why this
is not allowed; even if it is
guaranteed that the thread has
finished (see example code below).
My guestimation is that Threads might be directly tied (for efficiency or other constrains) to actual native resources that might be re-startable in some operating systems, but not in others. If the designers of the Java language had allowed Threads to be re-started, they might limit the number of operating systems on which the JVM can run.
Come to think of it, I cannot think of a OS that allows a thread or process to be restarted once it is finished or terminated. When a process completes, it dies. You want another one, you restart it. You never resurrect it.
Beyond the issues of efficiency and limitations imposed by the underlying OS, there is the issue of analysis and reasoning. You can reason about concurrency when things are either immutable or have a discrete, finite life-time. Just like state machines, they have to have a terminal state. Is it started, waiting, finished? Things like that cannot be easily reasoned about if you allow Threads to resurrect.
You also have to consider the implications of resurrecting a thread. Recreate its stack, its state, is is safe to resurrect? Can you resurrect a thread that ended abnormally? Etc.
Too hairy, too complex. All that for insignificant gains. Better to keep Threads as non-resurrectable resources.
I'd pose the question the other way round - why should a Thread object be restartable?
It's arguably much easier to reason about (and probably implement) a Thread that simply executes its given task exactly once and is then permanently finished. To restart threads would require a more complex view on what state a program was in at a given time.
So unless you can come up with a specific reason why restarting a given Thread is a better option than just creating a new one with the same Runnable, I'd posit that the design decision is for the better.
(This is broadly similar to an argument about mutable vs final variables - I find the final "variables" much easier to reason about and would much rather create multiple new constant variables rather than reuse existing ones.)
Because they didn't design it that way. From a clarity standpoint, that makes sense to me. A Thread represents a thread of execution, not a task. When that thread of execution has completed, it has done its work and it just muddies things were it to start at the top again.
A Runnable on the other hand represents a task, and can be submitted to many Threads as many times as you like.
Why don't you want to create a new Thread? If you're concerned about the overhead of creating your MyThread object, make it a Runnable and run it with a new Thread(myThread).start();
Java Threads follow a lifecycle based on the State Diagram below. Once the thread is in a final state, it is over. That is simply the design.
You can kind of get around this, either by using a java.util.concurrent.ThreadPoolExecutor, or manually by having a thread that calls Runnable.run() on each Runnable that it is given, not actually exiting when it is finished.
It's not exactly what you were asking about, but if you are worried about thread construction time then it can help solve that problem. Here's some example code for the manual method:
public class ReusableThread extends Thread {
private Queue<Runnable> runnables = new LinkedList<Runnable>();
private boolean running;
public void run() {
running = true;
while (running) {
Runnable r;
try {
synchronized (runnables) {
while (runnables.isEmpty()) runnables.wait();
r = runnables.poll();
}
}
catch (InterruptedException ie) {
// Ignore it
}
if (r != null) {
r.run();
}
}
}
public void stopProcessing() {
running = false;
synchronized (runnables) {
runnables.notify();
}
}
public void addTask(Runnable r) {
synchronized (runnables) {
runnables.add(r);
runnables.notify();
}
}
}
Obviously, this is just an example. It would need to have better error-handling code, and perhaps more tuning available.
If you are concerned with the overhead of creating a new Thread object then you can use executors.
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Testes {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Testes.A());
executor.execute(new Testes.A());
executor.execute(new Testes.A());
}
public static class A implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getId());
}
}
}
Running this you will see that the same thread is used for all Runnable objects.
A Thread is not a thread. A thread is an execution of your code. A Thread is an object that your program uses to create and, manage the life-cycle of, a thread.
Suppose you like playing tennis. Suppose you and your friend play a really awesome set. How would your friend react if you said, "That was incredible, let's play it again." Your friend might think you were nuts. It doesn't make sense even to talk about playing the same set again. If you play again you're playing a different set.
A thread is an execution of your code. It doesn't make sense to even talk about "re-using" a thread of execution for same reason that it makes no sense to talk about re-playing the same set in tennis. Even if another execution of your code executes all the same statements in the same order, it's still a different execution.
Andrzej Doyle's asked, "Why would you want to re-use a Thread?" Why indeed? If a Thread object represents a thread of execution---an ephemeral thing that you can't even talk about re-using---then why would you want or expect the Thread object to be re-useable?
i've been searching the same solution which you seem to be looking for, and i resolved it in this way. if you occur mousePressed Event you can terminate it also reuse it, but it need to be initialized, as you can see below.
class MouseHandler extends MouseAdapter{
public void mousePressed(MouseEvent e) {
if(th.isAlive()){
th.interrupt();
th = new Thread();
}
else{
th.start();
}
}
}

ThreadPoolExecutor's getActiveCount()

I have a ThreadPoolExecutor that seems to be lying to me when I call getActiveCount(). I haven't done a lot of multithreaded programming however, so perhaps I'm doing something incorrectly.
Here's my TPE
#Override
public void afterPropertiesSet() throws Exception {
BlockingQueue<Runnable> workQueue;
int maxQueueLength = threadPoolConfiguration.getMaximumQueueLength();
if (maxQueueLength == 0) {
workQueue = new LinkedBlockingQueue<Runnable>();
} else {
workQueue = new LinkedBlockingQueue<Runnable>(maxQueueLength);
}
pool = new ThreadPoolExecutor(
threadPoolConfiguration.getCorePoolSize(),
threadPoolConfiguration.getMaximumPoolSize(),
threadPoolConfiguration.getKeepAliveTime(),
TimeUnit.valueOf(threadPoolConfiguration.getTimeUnit()),
workQueue,
// Default thread factory creates normal-priority,
// non-daemon threads.
Executors.defaultThreadFactory(),
// Run any rejected task directly in the calling thread.
// In this way no records will be lost due to rejection
// however, no records will be added to the workQueue
// while the calling thread is processing a Task, so set
// your queue-size appropriately.
//
// This also means MaxThreadCount+1 tasks may run
// concurrently. If you REALLY want a max of MaxThreadCount
// threads don't use this.
new ThreadPoolExecutor.CallerRunsPolicy());
}
In this class I also have a DAO that I pass into my Runnable (FooWorker), like so:
#Override
public void addTask(FooRecord record) {
if (pool == null) {
throw new FooException(ERROR_THREAD_POOL_CONFIGURATION_NOT_SET);
}
pool.execute(new FooWorker(context, calculator, dao, record));
}
FooWorker runs record (the only non-singleton) through a state machine via calculator then sends the transitions to the database via dao, like so:
public void run() {
calculator.calculate(record);
dao.save(record);
}
Once my main thread is done creating new tasks I try and wait to make sure all threads finished successfully:
while (pool.getActiveCount() > 0) {
recordHandler.awaitTermination(terminationTimeout,
terminationTimeoutUnit);
}
What I'm seeing from output logs (which are presumably unreliable due to the threading) is that getActiveCount() is returning zero too early, and the while() loop is exiting while my last threads are still printing output from calculator.
Note I've also tried calling pool.shutdown() then using awaitTermination but then the next time my job runs the pool is still shut down.
My only guess is that inside a thread, when I send data into the dao (since it's a singleton created by Spring in the main thread...), java is considering the thread inactive since (I assume) it's processing in/waiting on the main thread.
Intuitively, based only on what I'm seeing, that's my guess. But... Is that really what's happening? Is there a way to "do it right" without putting a manual incremented variable at the top of run() and a decremented at the end to track the number of threads?
If the answer is "don't pass in the dao", then wouldn't I have to "new" a DAO for every thread? My process is already a (beautiful, efficient) beast, but that would really suck.
As the JavaDoc of getActiveCount states, it's an approximate value: you should not base any major business logic decisions on this.
If you want to wait for all scheduled tasks to complete, then you should simply use
pool.shutdown();
pool.awaitTermination(terminationTimeout, terminationTimeoutUnit);
If you need to wait for a specific task to finish, you should use submit() instead of execute() and then check the Future object for completion (either using isDone() if you want to do it non-blocking or by simply calling get() which blocks until the task is done).
The documentation suggests that the method getActiveCount() on ThreadPoolExecutor is not an exact number:
getActiveCount
public int getActiveCount()
Returns the approximate number of threads that are actively executing tasks.
Returns: the number of threads
Personally, when I am doing multithreaded work such as this, I use a variable that I increment as I add tasks, and decrement as I grab their output.

Waiting on threads

I have a method that contains the following (Java) code:
doSomeThings();
doSomeOtherThings();
doSomeThings() creates some threads, each of which will run for only a finite amount of time. The problem is that I don't want doSomeOtherThings() to be called until all the threads launched by doSomeThings() are finished. (Also doSomeThings() will call methods that may launch new threads and so on. I don't want to execute doSomeOtherThings() until all these threads have finished.)
This is because doSomeThings(), among other things will set myObject to null, while doSomeOtherThings() calls myObject.myMethod() and I do not want myObject to be null at that time.
Is there some standard way of doing this kind of thing (in Java)?
You may want to have a look at the java.util.concurrent package. In particular, you might consider using the CountDownLatch as in
package de.grimm.game.ui;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args)
throws Exception {
final ExecutorService executor = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(3);
for( int k = 0; k < 3; ++k ) {
executor.submit(new Runnable() {
public void run() {
// ... lengthy computation...
latch.countDown();
}
});
}
latch.await();
// ... reached only after all threads spawned have
// finished and acknowledged so by counting down the
// latch.
System.out.println("Done");
}
}
Obviously, this technique will only work, if you know the number of forked threads beforehand, since you need to initialize the latch with that number.
Another way would be to use condition variables, for example:
boolean done = false;
void functionRunInThreadA() {
synchronized( commonLock ) {
while( !done ) commonLock.wait();
}
// Here it is safe to set the variable to null
}
void functionRunInThreadB() {
// Do something...
synchronized( commonLock ) {
done = true;
commonLock.notifyAll();
}
}
You might need to add exception handling (InteruptedException) and some such.
Take a look at Thread.join() method.
I'm not clear on your exact implementation but it seems like doSomeThings() should wait on the child threads before returning.
Inside of doSomeThings() method, wait on the threads by calling Thread.join() method.
When you create a thread and call that thread's join() method, the calling thread waits until that thread object dies.
Example:
// Create an instance of my custom thread class
MyThread myThread = new MyThread();
// Tell the custom thread object to run
myThread.start();
// Wait for the custom thread object to finish
myThread.join();
You are looking is the executorservice and use the futures :)
See http://java.sun.com/docs/books/tutorial/essential/concurrency/exinter.html
So basically collect the futures for all the runnables that you submit to the executor service. Loop all the futures and call the get() methods. These will return when the corresponding runnable is done.
Another useful more robust Synchronization Barrier you can use that would do the similar functionality as a CountdownLatch is a CyclicBarrier. It works similar to a CountdownLatch where you have to know how many parties (threads) are being used, but it allows you to reuse the barrier as apposed to creating a new instance of a CountdownLatch every time.
I do like momania's suggestion of using an ExecutorService, collecting the futures and invoking get on all of them until they complete.
Another option is to sleep your main thread, and have it check every so often if the other threads have finished. However, I like Dirk's and Marcus Adams' answers better - just throwing this out here for completeness sake.
Depends on what exactly you are trying to do here. Is your main concern the ability to dynamically determine the various threads that get spawned by the successive methods that get called from within doSomeThings() and then be able to wait till they finish before calling doSomeOtherThings() ? Or it is possible to know the threads that are spawned at compile time ? In the later case there are number of solutions but all basically involve calling the Thread.join() method on all these threads from wherever they are created.
If it is indeed the former , then you are better off using ThreadGroup and its enumerate()
method. This gives you a array of all threads spawned by doSomeThings() if you have properly added new threads to the ThreadGroup. Then you can loop through all thread references in the returned array and call join() on the main thread just before you call doSomeOtherThings() .

How to make a Java thread wait for another thread's output?

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.
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();
I would really recommend that you go through a tutorial like Sun's Java Concurrency before you commence in the magical world of multithreading.
There are also a number of good books out (google for "Concurrent Programming in Java", "Java Concurrency in Practice".
To get to your answer:
In your code that must wait for the dbThread, you must have something like this:
//do some work
synchronized(objectYouNeedToLockOn){
while (!dbThread.isReady()){
objectYouNeedToLockOn.wait();
}
}
//continue with work after dbThread is ready
In your dbThread's method, you would need to do something like this:
//do db work
synchronized(objectYouNeedToLockOn){
//set ready flag to true (so isReady returns true)
ready = true;
objectYouNeedToLockOn.notifyAll();
}
//end thread run method here
The objectYouNeedToLockOn I'm using in these examples is preferably the object that you need to manipulate concurrently from each thread, or you could create a separate Object for that purpose (I would not recommend making the methods themselves synchronized):
private final Object lock = new Object();
//now use lock in your synchronized blocks
To further your understanding:
There are other (sometimes better) ways to do the above, e.g. with CountdownLatches, etc. Since Java 5 there are a lot of nifty concurrency classes in the java.util.concurrent package and sub-packages. You really need to find material online to get to know concurrency, or get a good book.
Requirement ::
To wait execution of next thread until previous finished.
Next thread must not start until previous thread stops, irrespective of time consumption.
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.
A lot of correct answers but without a simple example.. Here is an easy and simple way how 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
public class ThreadEvent {
private final Object lock = new Object();
public void signal() {
synchronized (lock) {
lock.notify();
}
}
public void await() throws InterruptedException {
synchronized (lock) {
lock.wait();
}
}
}
Use this class like this then:
Create a ThreadEvent:
ThreadEvent resultsReady = new ThreadEvent();
In the method this is waiting for results:
resultsReady.await();
And in the method that is creating the results after all the results have been created:
resultsReady.signal();
EDIT:
(Sorry for editing this post, but this code has a very bad race condition and I don't have enough reputation to comment)
You can only use this if you are 100% sure that signal() is called after await(). This is the one big reason why you cannot use Java object like e.g. Windows Events.
The if the code runs in this order:
Thread 1: resultsReady.signal();
Thread 2: resultsReady.await();
then thread 2 will wait forever. This is because Object.notify() only wakes up one of the currently running threads. A thread waiting later is not awoken. This is very different from how I expect events to work, where an event is signalled until a) waited for or b) explicitly reset.
Note: Most of the time, you should use notifyAll(), but this is not relevant to the "wait forever" problem above.
Try CountDownLatch class out of the java.util.concurrent package, which provides higher level synchronization mechanisms, that are far less error prone than any of the low level stuff.
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.
The Future interface from the java.lang.concurrent package is designed to provide access to results calculated in another thread.
Take a look at FutureTask and ExecutorService for a ready-made way of doing this kind of thing.
I'd strongly recommend reading Java Concurrency In Practice to anyone interested in concurrency and multithreading. It obviously concentrates on Java, but there is plenty of meat for anybody working in other languages too.
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.
This applies to all languages:
You want to have an event/listener model. You create a listener to wait for a particular event. The event would be created (or signaled) in your worker thread. This will block the thread until the signal is received instead of constantly polling to see if a condition is met, like the solution you currently have.
Your situation is one of the most common causes for deadlocks- make sure you signal the other thread regardless of errors that may have occurred. Example- if your application throws an exception- and never calls the method to signal the other that things have completed. This will make it so the other thread never 'wakes up'.
I suggest that you look into the concepts of using events and event handlers to better understand this paradigm before implementing your case.
Alternatively you can use a blocking function call using a mutex- which will cause the thread to wait for the resource to be free. To do this you need good thread synchronization- such as:
Thread-A Locks lock-a
Run thread-B
Thread-B waits for lock-a
Thread-A unlocks lock-a (causing Thread-B to continue)
Thread-A waits for lock-b
Thread-B completes and unlocks lock-b
You could read from a blocking queue in one thread and write to it in another thread.
Since
join() has been ruled out
you have already using CountDownLatch and
Future.get() is already proposed by other experts,
You can consider other alternatives:
invokeAll from ExecutorService
invokeAll(Collection<? extends Callable<T>> tasks)
Executes the given tasks, returning a list of Futures holding their status and results when all complete.
ForkJoinPool or newWorkStealingPool from Executors ( since Java 8 release)
Creates a work-stealing thread pool using all available processors as its target parallelism level.
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.

Categories