user10386436
user10386436

Reputation:

Java - Thread using executor service

I'm learning executor service in java. Requirement is using executor service create 4 threads -

Thread 1 - get two numbers as input.

Thread 2 - addition of two numbers

Thread 3 - multiplication of two numbers

Thread 4 - print the results.

Thread 1 should be executed first, after thread 1 is complete thread 2, 3 can start processing simultaneously and finally once thread 2, 3 is completed. Thread 4 should run finally.

How can we make sure which thread starts first and which threads to start simultaneously next. Finally which thread to execute at last.

Note: How can we achieve this without using thread sleep. Dynamically as soon as thread 1 finishes other two threads should start automatically.

Upvotes: 0

Views: 245

Answers (2)

Solomon Slow
Solomon Slow

Reputation: 27115

First, Read my comment on your original question--the one about using a car to hammer in nails.

Ok, Now, @dan1st had some ideas about how to structure the solution. Here's two more.

  1. Use a global int variable, a global lock, and wait() and notifyAll(): Have each thread enter a synchronized(lock) block in which it

    • Loops, calling lock.wait() until the global int has some particular value,
    • Does its trick,
    • Sets the global int to the value that will trigger the next thread,
    • calls lock.notify(), and finally
    • exits
  2. Use Semaphores: Pass two Semaphore instances in to each thread. Call them in and out or some such names. Have each thread

    • wait its turn by calling in.acquire(),
    • do its trick,
    • call out.release(),
    • and then exit.

Your main routine then is responsible for creating the semaphores, and passing them to the new threads in such a way that each thread's out refers to the same semaphore as the in of the thread that is expected to perform the subsequent task.


IMO, option 2 is more elegant, because if your teacher asks you next week to modify your program by adding another step in the middle of the sequence, then none of the existing tasks that you wrote will have to change at all. You'll only need to write the new task and change two or three lines in the main() routine.

Doesn't sound like much of an improvement, and option 2 clearly is more work to set up in the first place than option 1, but if you ever are employed to work on enterprise-scale software systems with millions of lines of code, you will come to appreciate the beauty of option 2.

Upvotes: 2

dan1st
dan1st

Reputation: 16338

You could do this using multiple ways.

For exanple, joining:

A Thread can join another Thread, which means that it waits until the other Thread finishes. Thread 2 and 3 could join Thread 1 and Thread 4 could join Thread 2 and 3.

Another possibility is await and signal but I am not sure if it meets your Requirements(it uses something similar to Thread.sleep():

At first, you create a common java.util.concurrent.locks.Lock and create a condition of this lock with .newCondition() You also create a second condition using newCondition().

The lock has to be locked before calling await and signal/signalAll.

Thread 2 and 3 calls .await() on the first condition before starting and Thread 1 calls .signalAll on the first condition when it finishes.

Thread 4 calls .await() on the second condition before it starts.

The Thread (either 2 or 3) that finishes last(the logic which Thread finished first should be synchronized with the lock) calls .signal() on the second condition.

The threads could also start each other:

Thread 1 starts Thread 2 and 3 after it's task finishes but I would recommand you one of the other mechanisms for Thread 4.

[DISCLAIMER]

You may not be able to interact with the Threads directly if you use an ExecutorService. This post might help you with joining, await/signal should not be more difficult and the Threads can also schedule a task to the thread pool if needed.

Upvotes: 1

Related Questions