aspose file tools*
The moose likes Threads and Synchronization and the fly likes How can I serialize thread handling with Java 5's java.util.concurrent package? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "How can I serialize thread handling with Java 5 Watch "How can I serialize thread handling with Java 5 New topic
Author

How can I serialize thread handling with Java 5's java.util.concurrent package?

Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Hi,

I like to serialize the thread handling of my jobs. See the example below:

I've 2 threads, A and B. In each Thread I've 2 jobs A1, A2 and B1, B2.


A |-----------[ A1 ]-------------[ A2 ]------------> t

B |-----------[ B1 ]-------------[ B2 ]------------> t


How can I make sure that my jobs are called by their thread in a user defined sequence, say A1,B1,B2,A2 or A1,B1,A2,B2?

At the moment I'm reading about Java 5's java.util.concurrent library, but so far I have no clue on how to achieve above requirement.

Any hints?
[ October 29, 2007: Message edited by: Darya Akbari ]

SCJP, SCJD, SCWCD, SCBCD
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

How can I make sure that my jobs are called by their thread in a user defined sequence, say A1,B1,B2,A2 or A1,B1,A2,B2?

At the moment I'm reading about Java 5's java.util.concurrent library, but so far I have no clue on how to achieve above requirement.



If you need an exact order, then you shouldn't be using threads -- since, they won't be running in parallel anyway.


However, if you need both threads to finish there "1" task first, before they both go do their "2" task, then there is a class in the java.util.concurrent library that would help. Take a look at the CyclicBarrier class.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Thanks Henry,

I'll read that info and see whether I get some results from it. By the way I'm currently reading Java Concurrency in Practice.
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Can we say that I need multiple Barriers depending on the number of jobs?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
You can say that, sure. You may also be able to use a single CyclicBarrier and just keep resetting it so you can reuse it. Another class to look into is CountDownLatch - you could associate a different CountDownLatch with each task, using a count of 1. The latch can be used to force the task to wait until the countDown() signal is sent by whoever controls the task order. You could also use a Lock and Condition.await(), or use a wait()/notify() protocol - but I think the CountDownLatch will be a little simpler.

Another possibility is to remove any instantiation of new Threads in your code, and instead use an ExecutorService for everything. To control the exact order of execution, write a custom ExecutorService that uses only a single thread, and write the logic to control which new task is chosen each time a task completes. This is really just an extension of Henry's suggestion to not use threads - but using ExecutorService allows you to abstract that decision out of most of the code, so that you could for example have multiple threads in production, but substitute a single-threaded tightly-controlled ExecutorService to certain types of testing (if that's what you want.)

I don't think I really understand your true goals here. That is, exact control of all aspects of the order such as you originally described is probably not practical or even possible, but partial control may be. You haven't explained your goals enough to say whether that will be acceptable. Why do you need to execute these tasks in a particular sequence? Why are you using threads at all?


"I'm not back." - Bill Harding, Twister
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Hi Jim,

Originally posted by Jim Yingst:
Another possibility is to remove any instantiation of new Threads in your code, and instead use an ExecutorService for everything. To control the exact order of execution, write a custom ExecutorService that uses only a single thread, and write the logic to control which new task is chosen each time a task completes. This is really just an extension of Henry's suggestion to not use threads - but using ExecutorService allows you to abstract that decision out of most of the code, so that you could for example have multiple threads in production, but substitute a single-threaded tightly-controlled ExecutorService to certain types of testing (if that's what you want.)


Well that's exactly what I want, I just have to find out how .

Originally posted by Jim Yingst:
I don't think I really understand your true goals here. That is, exact control of all aspects of the order such as you originally described is probably not practical or even possible, but partial control may be. You haven't explained your goals enough to say whether that will be acceptable. Why do you need to execute these tasks in a particular sequence? Why are you using threads at all?


The main reason why I want this approach is Swing GUI's Single Threadness. All my views heavily depend on lengthy server side communication. See the example view below:



It shows a JList with a list of show case names. Each show case is implemented as a Stateless Session Bean with an interface with 2 methods getName() and execute(). Beside the JList the view has a JButton.

The view depends on two Server Swing Worker Actions. The first one is responsible to initialize the JList with a collection of EJB JNDI names. This must happen before anything else. My view is started in the EDT thread and the Initialization task has to fork off into another thread to prepare the collection for the JList with JNDI and finally returns to the EDT thread. Now I can start the second Server Swing Worker action in the Execute thread to call the selected show case. This should happen when one click on the Execute button and after the Initialization task has finished.
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
I have another problem, is it possible to run two tasks in one and the same Thread .

When I want to simulate Swings's EDT thread behavior then I should be able to create a Thread A (as a placeholder for EDT) and assign my Tasks (Jobs, Runnable, etc.) to that thread.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Originally posted by Darya Akbari:
I have another problem, is it possible to run two tasks in one and the same Thread .

When I want to simulate Swings's EDT thread behavior then I should be able to create a Thread A (as a placeholder for EDT) and assign my Tasks (Jobs, Runnable, etc.) to that thread.



As Jim said, create a thread pool executor of size one (number of threads), and assign your tasks to it. Since the executor only has one thread, it is guaranteed that all tasks will be using the same thread.

Henry
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Darya]: I have another problem, is it possible to run two tasks in one and the same Thread .

Yes, provided they can be run serially. If Task 1 ever bloacks waiting for something to happen in task 2, that will be a problem. But in general if you can run task 1 to completion, then task 2, fine.
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
OK I'm going to use two ThreadPoolExecutor objects for all A and B tasks.



Would that make sense?
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Originally posted by Jim Yingst:
[Darya]: I have another problem, is it possible to run two tasks in one and the same Thread .

Yes, provided they can be run serially. If Task 1 ever bloacks waiting for something to happen in task 2, that will be a problem. But in general if you can run task 1 to completion, then task 2, fine.


Did you have Henry's suggestion in mind or a classical approach? I've nothing against the Executor approach. At the moment I think about how to merge this approach with the CyclicBarrier.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Henry's last suggestion began with "as Jim said", so yes, we're talking about the same thing. He filled in some additional details. I was just adding the point that depending on the nature of the tasks invovled, it may not be possible to process them serially. Or it may be that they can only be processed in a certain order - in which case it's your responsibility to get the order right.
[ October 24, 2007: Message edited by: Jim Yingst ]
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Going back to the original description which I took as two threads, each one executing a series of jobs in order. You can do that with two queues

Now you know A1 will run before A2, and B1 will run before B2, but you know nothing about how the As will relate to the Bs. An Executor with a max of 1 thread is a perfectly good substitute for QueueRunner.

I think the problem may have evolved since then so I'm not sure if that helps.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
I wonder about how the executor works. When I call .

The result is:


Why does the thread work on A2
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Hi Stan,

thanks for being part here . When I understand it right from the Executor description in JCiP (p. 117 2nd para) one should go with the Executor's execute() method and not with new Thread().start().

But as you say your solution is a substitute for the Executor approach.
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
OK, I don't know why my last try didn't work hence I tried this one:



The result from above main method is:



Now having my tasks run in their specific threads I'm back to my 2nd problem on how to synchronize them between threads.

Honestly, I'm little bit confused now :roll: . Would a CyclicBarrier or a CountDownLatch do me a favor here ?
[ October 25, 2007: Message edited by: Darya Akbari ]
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Using CyclicBarrier does not make any difference to the output .


[ October 25, 2007: Message edited by: Darya Akbari ]
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Tasks look like:



or concrete


[ October 25, 2007: Message edited by: Darya Akbari ]
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
I'm trying to run my tasks in this sequence A1,B1,A2,B2 with my solution shown previously. At least that was how I understood you :roll: .

A |-----[ A1 ]--------[ A2 ]------------> t

B |------------[ B1 ]--------[ B2 ]-----> t


Any idea, why it's not working? I'm not sure concerning the CyclicBarrier, it smells that one has to create a kind of barrier plan .
[ October 25, 2007: Message edited by: Darya Akbari ]
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

I know that I am missing something here, but what's is wrong with just this...



Henry
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Originally posted by Henry Wong:
I know that I am missing something here, but what's is wrong with just this...



Well, here you run all tasks in one Thread. However I want the A tasks to run in Thread A and the B tasks to run in Thread B. And this in a sequence A1,B1,A2,B2.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

The purpose of a barrier (and a countdown latch) is to have all the threads meet at a point, and then continue on. An example of would be...

We take a bus to go to a mall to go shopping, agree to all meet at a certain location, so that we can get on the bus, to head over to another mall.... but during that time, in the mall, you can do whatever you want -- you just have to meet at the prescribe location when you are done.

You don't care who does what when, you just care about the one meeting point.


Anyway, back to the first paragraph of the first response to this thead.

If you need an exact order, then you shouldn't be using threads -- since, they won't be running in parallel anyway.



If you really really want to do this, then you will have to write your own stuff. Have each task check to see if the previous task is done. If it is not, then reinsert itself back into the executor, and exit. If it is, then do its stuff, and set a flag, so that the next task can check on it.

If this sounds like a lot of work for something simple, it kinda is. Remember, you are trying to *not* use threads with threads.

Henry
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Originally posted by Henry Wong:
The purpose of a barrier (and a countdown latch) is to have all the threads meet at a point, and then continue on. An example of would be...

We take a bus to go to a mall to go shopping, agree to all meet at a certain location, so that we can get on the bus, to head over to another mall.... but during that time, in the mall, you can do whatever you want -- you just have to meet at the prescribe location when you are done.

You don't care who does what when, you just care about the one meeting point.


That's exactly what I do not want and my reasoning involving EDT in Swing was a little bit misleading. Because the EDT example's behavior fits exactly to your example above.

I'll try to give a better reasoning why I really want the synchronization of tasks and threads ...
Darya Akbari
Ranch Hand

Joined: Aug 21, 2004
Posts: 1855
Henry,

First of all, thanks for your time and help in this thread.

Originally posted by Henry Wong:
Anyway, back to the first paragraph of the first response to this thread.

[If you need an exact order, then you shouldn't be using threads -- since, they won't be running in parallel anyway.]


In case of Java EE applications, the EJB container is the one who spawns a thread for each transaction. I use JBoss who use the ThreadPoolExecutor for this task. There are occasions where I need to control the exact order of all tasks running in such transactions.

Originally posted by Henry Wong:
If you really really want to do this, then you will have to write your own stuff. Have each task check to see if the previous task is done. If it is not, then reinsert itself back into the executor, and exit. If it is, then do its stuff, and set a flag, so that the next task can check on it.

If this sounds like a lot of work for something simple, it kinda is. Remember, you are trying to *not* use threads with threads.


With your last statement you put your finger right into my wound. I like to simulate above given scenario by the EJB container in a standalone application. However I have no clue how to tell each task to wait for the other. I know I would have rules like:

  • B1, A2 and B2 must wait for A1
  • A2 and B2 must wait for B1
  • B2 must wait for A2


  • But how do I have to implement these rules with the java.util.concurrent API?
    Stan James
    (instanceof Sidekick)
    Ranch Hand

    Joined: Jan 29, 2003
    Posts: 8791
    I'm not good with all the fancy thread stuff and stick to the very basics. If each task has a reference to some object shared with the next then each can notify() the next in sequence. You could build some mechanism into an abstract task, say a constructor with a "wait on" object and a "notify" object.

    Tasks can assume there is only one waiter and one notifier per gate to keep that simple. Maybe tasks can wait on themselves and notify each other? That would eliminate the gate objects.
    Darya Akbari
    Ranch Hand

    Joined: Aug 21, 2004
    Posts: 1855
    Stan,

    this sounds very promisingly and seems to be the solution for my problem . I think I can replace the term gate with java.util.concurrent's CountDownLatch, at least here is what the Concurrent API says: . A CountDownLatch initialized with a count of one serves as a simple on/off latch, or gate


    I'll give it a try and let you know.
    Darya Akbari
    Ranch Hand

    Joined: Aug 21, 2004
    Posts: 1855
    Stan triggered my brain with his description of low level wait and notify mechanism. Honestly, I don't believe you Stan that you are not good at the fancy thread stuff as you say .

    The result now looks as I want:

    Thread A: A1
    Thread B: B1
    Thread A: A2
    Thread B: B2

    I've changed my abstract Task class and changed my Test Drive class a bit:

    Here the abstract Task class:


    ... and the Test Drive class:


    [ October 29, 2007: Message edited by: Darya Akbari ]
    Val�ry Urbain
    Greenhorn

    Joined: Oct 21, 2007
    Posts: 11
    You could get away with using just CountDownLatches. For example:

    using the above the test drive class becomes:


    On my system (Pentium 4 CPU dual core) running the test gave:
    About to start the worker threads..
    Thread-0: org.javaranch.threads.AbstractTask$TaskA[A1]
    Thread-2: org.javaranch.threads.AbstractTask$TaskB[B1]
    main thread is doing something else here.
    Thread-1: org.javaranch.threads.AbstractTask$TaskA[A2]
    Thread-3: org.javaranch.threads.AbstractTask$TaskB[B2]

    or
    About to start the worker threads..
    main thread is doing something else here.
    Thread-0: org.javaranch.threads.AbstractTask$TaskA[A1]
    Thread-2: org.javaranch.threads.AbstractTask$TaskB[B1]
    Thread-1: org.javaranch.threads.AbstractTask$TaskA[A2]
    Thread-3: org.javaranch.threads.AbstractTask$TaskB[B2]


    The relative tasks' ordering is enforced by the particular usage of latches.
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: How can I serialize thread handling with Java 5's java.util.concurrent package?