• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

concurrency

 
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys! I'm a bit confused with a concurrency in java... Here is a situation: I need to do some resource intense operation in separate thread and then retrieve the result to parent thread, plus parent thread should wait until he has data.
So I have Thread1 which triggers Thread2 and waiting until it is finished. Once the Thread2 has done it's work it has to pass all processed data to the Thread1. What is the best way to do that? I made a setter method in Thread1 so that my Thread2 could use it to pass data to a field of Thread1 and then wake it up, but it doesn't work that way (the Thread1 waking up but it's data field is still null) I think the problem is that the Thread1 is waiting, so my setter doesn't work. I guess my explanaition is a bit confusing so here is some code sample to make it more understandable:


Please help me to figure it out, guys.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, small remark: the reason to call Thread2 and make Thread1 to wait is that in real code there will be N (N > 1) child threads, each doing it's own job. And once all child threads are done, parent thread sould wake up and do it's job.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If the thread that triggers the operation in a second thread has to wait for the result, then what's the point of doing the work in a separate thread? You could just as well do it in a single thread then.

You could use an ExecutorService for this. Submit a Callable to the ExecutorService. That will return a Future, from which you can get the result of the computation thread. When you call get() on the Future, your thread will return the result of the computation thread, or if the computation thread isn't ready yet, it will wait until it's ready and then return the result.

Here's a simple example.

 
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aleksey Vladimirovich wrote:Oh, small remark: the reason to call Thread2 and make Thread1 to wait is that in real code there will be N (N > 1) child threads, each doing it's own job. And once all child threads are done, parent thread sould wake up and do it's job.


So if the parent thread doesn't need to do anything until all the child threads have completed why don't you just get the parent thread to call join on each of the children after it has started them ?
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesper de Jong wrote:If the thread that triggers the operation in a second thread has to wait for the result, then what's the point of doing the work in a separate thread? You could just as well do it in a single thread then.


I missed it in the first post, please read the second one.
 
Jesper de Jong
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your "small remark" changes the whole question...

If you have multiple threads doing the work, you could use a CountDownLatch. Create it with a starting number, the number of tasks that has to be performed. In the computation thread, count down the latch by one when the task is finished. In the main thread, make it wait until the CountDownLatch reaches zero (it has special methods for that). When it reaches zero, all tasks are done and you can collect the result.

Another possibility is to use the fork/join framework - whether that's appropriate depends on what the problem is exactly.

Another solution, which Joanne proposed, is to simply call join() on all computation threads from the main thread, in a loop - that will make the main thread wait until all computation threads have finished.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Joanne Neal wrote:

Aleksey Vladimirovich wrote:Oh, small remark: the reason to call Thread2 and make Thread1 to wait is that in real code there will be N (N > 1) child threads, each doing it's own job. And once all child threads are done, parent thread sould wake up and do it's job.


So if the parent thread doesn't need to do anything until all the child threads have completed why don't you just get the parent thread to call join on each of the children after it has started them ?


Sorry, I'm noob in Java. So, if I call join on all child threads, I'll be able to get data from them? I mean the parent thread won't wake up until all of them are finished? And here is what java docs say: "join() - Waits for this thread to die." So will I be able to get my data from them?
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesper de Jong wrote:Your "small remark" changes the whole question...
If you have multiple threads doing the work, you could use a CountDownLatch. Create it with a starting number, the number of tasks that has to be performed. In the computation thread, count down the latch by one when the task is finished. In the main thread, make it wait until the CountDownLatch reaches zero (it has special methods for that). When it reaches zero, all tasks are done and you can collect the result.


Unfortunately I have to work with ancient java 1.4 version in this particular case and there was no CountDownLatch in it, it is available since version 1.5.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aleksey Vladimirovich wrote:Sorry, I'm noob in Java. So, if I call join on all child threads, I'll be able to get data from them? I mean the parent thread won't wake up until all of them are finished? And here is what java docs say: "join() - Waits for this thread to die." So will I be able to get my data from them?


Not from them, but you could populate a shared structure, such as a Map or List with the data that the parent thread needs to know about; and if you use a Map, you could key it by something like Thread ID and probably not even need to synchronize it.

Winston
 
Rancher
Posts: 2759
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Since executor service is not available to you, you are better off implementing your own executor service. You can use a publisher consumer pattern. Have a queue that holds your jobs. The main thread posts jobs to the queue, and the worker threads takes jobs from the queue and process them. Have another queue that holds results, and the worker threads can posts results to the result queue as they finish a job. The main thread can monitor size of the queues. Once the results queue have all the results, take them out and process them.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you, guys! join() worked like a charm!
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jayesh A Lalwani wrote:Since executor service is not available to you, you are better off implementing your own executor service. You can use a publisher consumer pattern. Have a queue that holds your jobs. The main thread posts jobs to the queue, and the worker threads takes jobs from the queue and process them. Have another queue that holds results, and the worker threads can posts results to the result queue as they finish a job. The main thread can monitor size of the queues. Once the results queue have all the results, take them out and process them.


Actually I was intended to do that, thanks!
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Um, sorry for annoying you guys, but could anyone please explain me, how does join() works? I mean, if it makes parent thread to wait until children threads die how can I call join on the other threads besides first one? Or the method of parent thread keeps executing to the end and then when all children threads are done it triggers that method from the point where the last join(0 was called?
 
Jesper de Jong
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You start a number of threads, so you have a collection of Thread objects. Then you just loop over those Thread objects and call join() on each of them in the loop.

If the thread you call it on has already stopped, join() returns immediately. If it's still running, join() waits until the thread has stopped.

So if you call it in a loop on all Thread objects, then when the loop is done, all those threads have stopped.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesper de Jong wrote:You start a number of threads, so you have a collection of Thread objects. Then you just loop over those Thread objects and call join() on each of them in the loop.

If the thread you call it on has already stopped, join() returns immediately. If it's still running, join() waits until the thread has stopped.

So if you call it in a loop on all Thread objects, then when the loop is done, all those threads have stopped.


Oh, in that case it's not what I need I need all child threads run simultaneously, not sequentally... Or maybe I understood you wrong. You're saying that the parent thread waits for a response from each thread, join() method was called on, and only then does the same to the next thread (second child won't start until first is done), right? In that case there is no point in it
 
Joanne Neal
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Aleksey Vladimirovich wrote:You're saying that the parent thread waits for a response from each thread, join() method was called on, and only then does the same to the next thread (second child won't start until first is done), right? In that case there is no point in it


You store a reference to each thread in a collection. You then loop through the collection and call start on each thread. So all your threads are now running. You then loop through the collection again and call join on each thread. The call to join on the first thread won't return until the thread has completed, but during this time all the other threads are running as well. Once the call to join on the first thread returns, you call join on the second thread. It may be that the second thread has already completed, so join will return immediately but if it hasn't join will not return until it has. This repeats for all the threads in your loop.
 
Aleksey Vladimirovich
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Joanne Neal wrote:

Aleksey Vladimirovich wrote:You're saying that the parent thread waits for a response from each thread, join() method was called on, and only then does the same to the next thread (second child won't start until first is done), right? In that case there is no point in it


You store a reference to each thread in a collection. You then loop through the collection and call start on each thread. So all your threads are now running. You then loop through the collection again and call join on each thread. The call to join on the first thread won't return until the thread has completed, but during this time all the other threads are running as well. Once the call to join on the first thread returns, you call join on the second thread. It may be that the second thread has already completed, so join will return immediately but if it hasn't join will not return until it has. This repeats for all the threads in your loop.


Thanks a lot! Now I get it! Everything works how it supposed to
 
I have always wanted to have a neighbor just like you - Fred Rogers. Tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic