0

I have a list of objects that has to be shared among multiple threads.

For example, I have a 5 discrete objects and a pool of 20 threads. At first 5 of 20 threads will start working, leaving the other threads in WAIT state. 5 threads will utilize each of 5 objects at a same time.

If any of the thread is completed it should release the object so that the 6th thread can start working.

For parallel processing of threads I think I can use Executor pool. But how to share the list of objects among threads ?

3
  • Take a BlockingQueue (docs.oracle.com/javase/7/docs/api/java/util/concurrent/…) and put the objects back after you are finished Commented May 31, 2016 at 7:38
  • 1
    Is the 6th thread doing something different to the object than the 5th one? Why would you need more than 5 threads if you have only 5 objects. There's certainly no performance advantage in having 4 times the amount of threads you need. Commented May 31, 2016 at 8:01
  • Yes. All the 20 threads will have distinct operations even though they have same source code. Operations will differ based on the input supplied to the source code. As Gilfoy and Svetlin Zarev suggested, I am using one implementation that is perfectly working now. Thanks for your comments though. Commented Jun 1, 2016 at 16:39

5 Answers 5

2

I think you have your threading model wrong. Currently you want to share which is always wrong in a parallel environment. What you should do instead is to create a pipeline. To do so you have several options.

  1. Use a (blocking/concurrent) queue to pass the objects between threads. In this scenario you have a fixed number of worker threads of each stage of the pipeline that are always running and share the queue. On one side you have the producer threads, which when they finish put() the object to the queue and then one of the consumer threads take() the object and starts to process it.

  2. Use a threadpool to act as the queue from (1). Instead of doing put() on a shared queue you do submit()/execute() to a shared or a dedicated thread pool to pass the object to the next stage of the pipeline. The downside of this approach is that the current stage have to know the exact pool to which to submit the task and also to know how to create the runnable which is to be submitted.

PS: In my answer I assume that Thread-6 performs different kind of operations than the previous 5 threads. If this assumption is incorrect - solution (1) still stands correct and is the way forward.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. It works. You are correct. Each thread will perform different kind of operation.
1

Seems to me you are talking about Object pool pattern. Object pools are containers which contain a specified amount of objects. When an object is taken from the pool, it is not available in the pool until it is put back.

Pools should be used in cases such as:

  • High-frequency using of the same objects
  • Objects are very big and consume much memory
  • Objects need much time for initialization
  • Objects use massive IO operations (Streams, Sockets, DB, etc.)
  • Objects are not thread-safe

Some publications do not recommend using object pooling, especially for objects that only use memory and hold no external resources. Related criticism question.

Depends why do you need this pattern. Here is implementation in Java.

Comments

1

You can define the number of threads you want to run in parallel. For example,

ExecutorService executor = Executors.newFixedThreadPool(20);

Then you can write a for loop to processing the list of objects.

for(Object obj: objList) {
    Runnable thread = new MyThreadImpl(obj);
    executor.execute(thread);
}

This should work perfectly fine as per your

Comments

0

I doubt there is a standard implementation in JDK, but you could build your own object pool depending on your requirements or probably look into a library, e.g. https://commons.apache.org/proper/commons-pool/

Comments

0

Using Reentrant Locks

private static synchronized ReentrantLock getLock(Long id) {
    if (!locks.containsKey(id)) {
        locks.put(id, new ReentrantLock());
    }
    return locks.get(id);
}

private void lock(Long id) {
    ReentrantLock lock = getLock(id);
    lock.lock();
}

private void unlock(Long id) {
    ReentrantLock lock = getLock(id);
    if (lock.isHeldByCurrentThread()) {
        lock.unlock();
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.