Handling 10000 threads using Executor - java

I have a web service which is continuously accessed by more than 20 servers which are sending data. I have used activeMQ where data is queued for some time and than using async task this data is dequed.
My async task thread class is shown below.
public class myConsumer {
public void asyncConsumer() throws InterruptedException, ExecutionException{
final MyReceiver receiver = new MyReceiver();
final ExecutorService executorService = Executors.newSingleThreadExecutor();
try{
Future future = executorService.submit(new Runnable() {
public void run() {
receiver.receiveMessage();
}
});
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}catch (InterruptedException e) {
logger.error("tasks interrupted");
}finally {
if (!executorService.isTerminated()) {
logger.error("cancel non-finished tasks");
}
executorService.shutdownNow();
}
}
}
I have 10000 of threads running. My applcation server is stopped due to unusual behavior. How to handle this many no of thread using above code.

You should use a thread pool executor rather than single thread executor, and make sure it's only one instance of the thread pool receiving messages. This way you can keep track of and limit the amount of concurrent threads.
Here's an example of how it can be done. By having the executorservice static you assure that it's only one instance, and it's limited to max 10 simultaneous threads. When you call asyncConsumer to process a received message a MyReceiver (which I assume is going to process the message) is created and invoked inside the thread pool.
public class MyConsumer {
static final ExecutorService executorService = Executors.newFixedThreadPool(10);
public void asyncConsumer() {
Future future = executorService.submit(new Runnable() {
public void run() {
new MyReceiver().receiveMessage();
}
});
}
}

Related

When kills cacheThreadPool inactive threads? Java

the cacheThreadPool automatically deletes threads if they are inactive for 60 seconds, as far as I know. Only what exactly that means inactive is not clear to me.
My implementation looks like this:
public class ProcessHandler {
private class Worker implements Runnable {
private final LinkedBlockingQueue<MyTask> tasks = new LinkedBlockingQueue<>();
void schedule(List<MyTask> task) {
tasks.addAll(task);
}
#Override
public void run() {
while (true) {
try {
var task = tasks.take();
task.run();
} catch (InterruptedException ie) {
// perhaps, handle somehow
}
}
}
}
private ExecutorService esMultiThread = Executors.newCachedThreadPool();
public void submitProcess(List<MyTask> task){
Worker test = new Worker();
test.schedule(task);
esMultiThread.execute(test);
}
}
I create a Instance of ProcessHandler and then I want to submit task over and over again with submitProcess. Every new call of submitProcess should start a new thread so that everything is processed in parallel, e.g. if I call submitProcess 10 times fast in a row. These tasks should then be processed by a new Thread from the cachedThreadPool.
My question now, while the worker is sleeping, i.e. waiting by take(), will the thread be killed if the worker gets nothing for more than 60 seconds, or does the thread live infinitely because "sleeping" is a state which is not considered inactive by the cacheThreadPool?

How to cancel incomplete task on ExecutorService [duplicate]

This question already has answers here:
Java ExecutorService pause/resume a specific thread
(3 answers)
Closed 5 years ago.
I have submitted two tasks, task1 & task2 to the ExecutorService. Task2 needs 5 seconds to complete, and task1 need 10 seconds.
How can I stop the task(s) submitted (ie: task1) when task2 completes and continues the rest of logic?
Here's my code so far:
public class mt_poc {
public static void action_1 () throws InterruptedException {
System.out.println("action_1 invoke " );
Thread.sleep(10000);
action_2 ();
System.out.println("action_1 done" );
}
public static void action_2() throws InterruptedException {
System.out.println("action_2 invoke " );
Thread.sleep(5000);
System.out.println("action_2 done " );
}
public static void main(String[] args) {
System.out.println("TEST");
Runnable task1 = new Runnable() {
public void run() {
try {
action_1 ();
}
catch(InterruptedException e) {
System.out.println("action_1 invoke interrupted");
}
System.out.println("action_1 invoke run is over" );
}
};
Runnable task2 = new Runnable() {
public void run() {
try {
action_2 ();
}
catch(InterruptedException e) {
System.out.println("action_2 invoke interrupted");
}
System.out.println("action_2 invoke run is over" );
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
try {
executor.submit(task1);
executor.submit(task2);
// cancel uncomplete task
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
// continues the rest of logic
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Shutdown executor");
}
}
you can use shutdownNow() method
Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution.
for full documentation:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html
shutdown() method will wait for all the threads to finish before closing the executor
You have to retrieve the Future objects from the submit function.
These are used to control the running thread and get the status of it.
If you have the futures, call Future2.get(). This will block the thread until the Task2 is finished. No you can use Future1.cancel(true) to abort the other thread.
But pausing and resuming is not possible. See Java ExecutorService pause/resume a specific thread
If you want such specific behaviour you need to use Threads.
But why you want to do this in seperate Threads as it would be much simpler and efficient t use a single one.

ExecutorService JVM doesn't terminate [duplicate]

This question already has answers here:
Java ServiceExecutor terminating condition
(4 answers)
Closed 7 years ago.
I don't understand why I have to call executorService.shutdown()
explicitly to terminate executorService.
If I will not call shutdown() then the JVM will not terminate on its own.
What is wrong with my program or what concept I am lacking?
public class ExecutorServiceExample {
public static class Task1 implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task1 :"
+ Thread.currentThread().getName());
}
}
public static class Task2 implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task2 :"
+ Thread.currentThread().getName());
}
}
public static class Task3 implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task3 :"
+ Thread.currentThread().getName());
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future future1 = executorService.submit(new Task1());
Future future2 = executorService.submit(new Task2());
Future future3 = executorService.submit(new Task3());
}
}
Output:
Message from Task2 :pool-1-thread-2
Message from Task1 :pool-1-thread-1
Message from Task3 :pool-1-thread-3
JVM is still alive. If I will call shutdown() then only JVM would die.
According to Thread javadoc:
The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
Your executor creates non-daemon threads which prevent your JVM from shutting down. Threads created by executors are usually pooled to run more than one task submitted to the executor - often this is a performance optimisation to reuse threads so they run more then one task (as creating new thread is an expensive operation). Depending on the implementation and configuration of the executor (e.g. see ThreadPoolExecutor doc, especially keepalive configuration) it might keep the threads running forever or terminate when they are unused for some time.
You must either call shutdown on your executor or create it with a custom ThreadFactory (e.g. using Executors.newFixedThreadPool(int, ThreadFactory)) where that thread factory will configure new threads as daemon ones.

Executor: Wait for specific tasks to finish

The server application I am running gets multiple requests for tasks which I want to handle using a task system.
Each task is represented as a Runnable that will demand n number of threads from a thread pool where n is smaller or equal to the thread pool size. The thread pool of course is necessary in order to not overload the CPU with too many threads.
However, some of those tasks can be multi threaded and some can not. That is why it might be necessary for one task to wait for all its specific threads to finish in order to merge the results from those threads for the final result.
If one uses multiple Thread instances one might join those like this:
try {
// Wait for all threads to finish their tasks
for (Thread thread : threads) {
thread.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// Finish job here ..
but I'd need something like this using java.util.concurrent.Executor or anything similar that works with a thread pool.
You can use ExecutorService along with a CyclicBarrier for each task as follows:
public class ThreadedTask implements Runnable {
CyclicBarrier barrier;
public ThreadedTask(CyclicBarrier barrier) {
this.barrier = barrier;
}
#Override
public void run() {
// do something
barrier.await();
}
}
ExecutorService executor = Executors.newFixedThreadPool(pool_size);
...
CyclicBarrier barrier = new CyclicBarrier(n+1);
for(int i=0; i<n; i++) {
// launch all tasks
executor.submit(new ThreadedTask(barrier));
}
// waits for the tasks to finish or timeout
barrier.await(seconds, TimeUnit.SECONDS);
If I understand you correctly, you will need something like this (but your architecture seems too complicated):
class MyTask implements Runnable {
#Override
public void run() {
// some work
}
}
After that:
ExecutorService executorService = Executors.newFixedThreadPool(2000);
ArrayList<Future> futures = new ArrayList<>();
futures.add(executorService.submit(new MyTask()));
futures.add(executorService.submit(new MyTask()));
futures.add(executorService.submit(new MyTask()));
for (Future future: futures) {
try {
future.get(100, TimeUnit.SECONDS);
} catch (Throwable cause) {
// process cause
}
}
Each future.get() will wait for task ending (max 100 seconds in this example).

Why does ExecutorService keep executing when threads are blocking?

I am trying to write a part of a multithreaded program where each thread from a fixed thread pool tries to fetch an object from a Queue and if the Queue is empty the thread waits.
The problem I am experiencing is that the memory used by the program keeps increasing.
public class Ex3 {
public static LinkedBlockingQueue<Integer> myLBQ = new LinkedBlockingQueue<Integer>(10);
public static void main(String argc[]) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
myLBQ.add(new Integer(1));
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
}
}
class MyHandler implements Runnable {
LinkedBlockingQueue<Integer> myLBQ;
MyHandler(LinkedBlockingQueue<Integer> myLBQ) {
this.myLBQ = myLBQ;
}
public void run() {
try {
myLBQ.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I don't understand why the executor.execute keeps firing when the threads should be waiting for an item to be added to the Queue. How do I modify my code to reflect this?
This adds tasks to the executor as fast as it can.
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
This will consume about 200 MB per second. It doesn't have anything to do with whether there are tasks to perform or not.
If you don't want to do this I suggest you move the loop to the runnable and add only one. This will cause it to wait for tasks forever.
A better approach is to use the ExecutorService's builtin queue to queue tasks.
ExecutorService executor = Executors.newFixedThreadPool(3);
final int taskId = 1;
executor.submit(new Runnable() {
#Override
public void run() {
doSomething(taskId);
}
});
executor.shutdown();
This does the same thing, but is much simpler IMHO.
it's because you're creating a gazillion instances of MyHandler and inserting them in the internal queue of the executor.
That infinite for loop is quite mean.

Categories