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.
Related
This is my simple code:
public class Main4 {
public static void main(String[] args) {
System.out.println("Hello from thread: "+Thread.currentThread().getName());
new Game().run();
System.out.println("I am dying ... ");
}
static class Game {
public void run() {
value();
}
private int value() {
int number = 0;
CompletionStage<Void> c = calculate().thenApply(i -> i + 3).thenAccept(i -> System.out.println("I am done, and my value is " + i));
return number;
}
private CompletionStage<Integer> calculate() {
CompletionStage<Integer> completionStage = new CompletableFuture<>();
Executors.newCachedThreadPool().submit(() -> {
System.out.println("I am in the thread: " + Thread.currentThread().getName());
try {
Thread.sleep(50000);
((CompletableFuture<Integer>) completionStage).complete(3);
} catch (Exception e) {
e.printStackTrace();
}
return null;
});
return completionStage;
}
}
}
The output of the execution is:
Hello from thread: main
I am in the thread: pool-1-thread-1
I am dying ...
But the thing is: the main thread doesn't terminate immediately, it waits for 50000 milliseconds. that is my question. I understood that it should terminate because there is no more things to execute.
Initially I thought that the reason is that the "sleep" is being executed in the main thread, and that's why I printed the names of the threads, and they're two different threads.
Help is appreciated.
I added time marks to the output of your program and also a shutdown hook so that JVM termination can be logged as well:
0s Hello from thread: main # `main` method starts
0s I am in the thread: pool-1-thread-1 # `Runnable` submitted to the executor starts
0s I am dying ... # `main` method exits
50s I am done, and my value is 6 # `Runnable` submitted to the executor finishes
110s exiting # JVM process exits
Non-daemon threads
The reason why the process continues after main method exits is that JVM needs to wait for all non-daemon threads to terminate before it shuts down. Executors produced using Executors class create non-daemon threads by default (see Executors.defaultThreadFactory() method javadoc).
Customizing ThreadFactory
You can override how the threads are created by passing a custom ThreadFactory to the Executors.newCachedThreadPool() method:
ExecutorService executorService = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t;
});
executorService will only have daemon threads in its thread pool.
Thread caching
But notice that the JVM still doesn't exit for 60 seconds after your thenAccept block is executed:
50s I am done, and my value is 6 # `Runnable` submitted to the executor finishes
110s exiting # JVM process exits
Why is that? It's explained in Executors.newCachedThreadPool() documentation (emphasis added):
Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources. Note that pools with similar properties but different details (for example, timeout parameters) may be created using ThreadPoolExecutor constructors.
This means that this thread pool does not dispose of the threads immediately after they finish doing scheduled tasks. It will instead do it's best to reuse previously created threads for new task submissions. This is the reason for the delay: after your task finishes the thread remains in the thread pool for reusal and only after the next 60 seconds it is destroyed (you only submit one task in your program). Only then the JVM can exit (because the thread is not a daemon thread as pointed above).
Shutting down the ExecutorService
Normally when working with an ExecutorService you should shut it down explicitly before the process is terminated. For this purpose use ExecutorService.shutdown() or ExecutorService.shutdownNow() methods. Refer to the documentation for the difference between these two.
References
What is a daemon thread in Java?
Turning an ExecutorService to daemon in Java
Program does not terminate immediately when all ExecutorService tasks are done
Modified program with time marks and JVM termination log:
public class Main {
private static final Instant start = Instant.now();
private static void debug(String message) {
System.out.println(Duration.between(start, Instant.now()).getSeconds() + "s " + message);
}
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> debug("exiting")));
debug("Hello from thread: "+Thread.currentThread().getName());
new Game().run();
debug("I am dying ... ");
}
static class Game {
public void run() {
value();
}
private int value() {
int number = 0;
CompletionStage<Void> c = calculate().thenApply(i -> i + 3).thenAccept(i -> debug("I am done, and my value is " + i));
return number;
}
private CompletionStage<Integer> calculate() {
CompletionStage<Integer> completionStage = new CompletableFuture<>();
Executors.newCachedThreadPool().submit(() -> {
debug("I am in the thread: " + Thread.currentThread().getName());
try {
Thread.sleep(50000);
((CompletableFuture<Integer>) completionStage).complete(3);
} catch (Exception e) {
e.printStackTrace();
}
return null;
});
return completionStage;
}
}
}
the main thread doesn't terminate immediately
That's because you create an ExecutorService which you never shut down. Here is your code with the inclusion of shutting down the ExecutorService.
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main4 {
public static void main(String[] args) {
System.out.println("Hello from thread: "+Thread.currentThread().getName());
new Game().run();
System.out.println("I am dying ... ");
}
static class Game {
public void run() {
value();
}
private int value() {
int number = 0;
CompletionStage<Void> c = calculate().thenApply(i -> i + 3).thenAccept(i -> System.out.println("I am done, and my value is " + i));
return number;
}
private CompletionStage<Integer> calculate() {
CompletionStage<Integer> completionStage = new CompletableFuture<>();
ExecutorService es = Executors.newCachedThreadPool();
es.submit(() -> {
System.out.println("I am in the thread: " + Thread.currentThread().getName());
try {
Thread.sleep(50000);
((CompletableFuture<Integer>) completionStage).complete(3);
} catch (Exception e) {
e.printStackTrace();
}
return null;
});
es.shutdown();
return completionStage;
}
}
}
The output from the above code is...
Hello from thread: main
I am dying ...
I am in the thread: pool-1-thread-1
I am done, and my value is 6
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.
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();
}
});
}
}
I have multiple threads of multiple types (Different classes). I want in case one of them throws an exception and dies to be replaced by another NEW thread. I am aware of the join thread function but how would I go about implementing them for 5 different type of threads such as in case type 1 thread dies is instantly replaced without having to wait for type 2 to die first.
This is some sample pseudo-code.
class1 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class2 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class3 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
public main(){
// start all threads .start()
}
I want in case one of them throws an exception and dies to be replaced by another NEW thread.
I don't quite understand why you can't do:
public void run() {
// only quit the loop if the thread is interrupted
while (!Thread.currentThread().isInterrupted()) {
try {
// do some stuff that might throw
repeat task;
} catch (Exception e) {
// recover from the throw here but then continue running
}
}
}
Why do you need to restart a NEW thread? Just because a task threw an exception doesn't mean that it is somehow corrupt and it needs a fresh one to work appropriately. If you are trying to catch all exceptions (including RuntimeException) then catch (Exception e) will do this. If you want to be really careful you can even catch Throwable in case there is a chance that Errors are being generated – this is relatively rare.
If you actually have multiple tasks (or really anytime you are dealing with threads), you should consider using the ExecutorService classes. See the Java tutorial.
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
// define your jobs somehow
threadPool.submit(new Class1());
threadPool.submit(new Class2());
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
So instead of forking a thread to do multiple tasks, you start a thread pool and it starts threads as necessary to accomplish a bunch of tasks. If a task fails, you could certain submit another task to the pool although that's a slightly strange pattern.
If you want to wait for all of the tasks to finish you'd use:
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
boolean shouldStop() {
// it's a good idea to think about how/when to stop ;)
return false;
}
void runThreadGivenType(final Runnable taskToRun) {
new Thread() {
#Override
public void run() {
try {
taskToRun.run();
} finally {
if (!shouldStop()) {
runThreadGivenType(taskToRun);
}
}
}
}.start();
}
public void main(String[] args) throws Exception {
runThreadGivenType(new Runnable() { public void run() { System.out.println("I'm almost immortal thread!"); throw new RuntimeException(); } });
TimeUnit.SECONDS.sleep(10);
}
and it's a good idea to think about executors to manage thread pools too. plain, [un/hand]-managed threads are not the best practice ;)
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.