0

I have a module which operates on thousands of transactions to process . Each transaction has multiple phases to go through. This module executes in multithreaded mode. We have defined limits (hardcoded)for number of threads it can create (limited as per server utilization ).

now we came accross a situation, where threads may need to wait for some period (may be more than 24 hours). As we have limited number of threads and if all threads are waiting for more than 24 hours, this is entirely blocking the application.

What i need here is, how should i reuse the thread which is under wait wait for 24 hour. if thread is going in wait mode, i need to reuse that thread for anather transaction and when original wait ends, restart the original transaction from where it was put on hold.

i hope above discription helps u to understand issue.

Krutik Jayswal
  • 3,165
  • 1
  • 15
  • 38
Vishal Jagtap
  • 551
  • 1
  • 6
  • 9
  • 1
    are you using the `ExecutorService` or some equivalent? Each "transaction" should be a task that should be able to be executed. If for any reason, the transaction cannot complete, it should be posted to a pending queue. You should have an independent thread monitoring this pending queue for tasks that are ready to execute, if there are any, post this to the executor service to execute on the next available thread. Sounds like a slight redesign of your existing architecture... – Nim Jan 31 '13 at 10:09
  • When you say "thread is going to wait for hours", do you mean "it will sleep for x hours and then try again" or "it is actively polling for some event that can happen any time between now and a few hours"? For the latter situation, I would favor a serialization solution. – SJuan76 Jan 31 '13 at 13:52

1 Answers1

0

If you have long delays in your system, the best thing to do is to have more threads. If you want to limit the number of threads running concurrently you can use permits e.g. a Semaphore which is released whenever you have blocking operation and re-acquired when the blocking finishes. This ensures you have a limited number of threads running at once but allows you to easily switch between many tasks.

public abstract class LimitedTask implements Runnable {
    static final Semaphore PERMITS = new Semaphore(Runtime.getRuntime().availableProcessors());

    @Override
    public final void run() {
        try {
            PERMITS.acquire();
        } catch (InterruptedException e) {
            System.err.println("Task " + getClass() + " cancelled before it was started.");
            return;
        }
        try {
            runTask();
        } finally {
            PERMITS.release();
        }
    }

    protected abstract void runTask();

    protected void runBlockingTask(Runnable runnable) {
        PERMITS.release();
        try {
            runnable.run();
        } finally {
            PERMITS.acquireUninterruptibly();
        }
    }
}

In this example, you can have as many of these as you want but only a limited number will be within the PERMIT area. The tasks can also call runBlockingTask() to allow it to perform a blocking task but allow another thread to run while it is blocking.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130