I'm new to Java Multithreading. Curious to know the state of idle thread incase of ThreadPoolExecutor. Is it in RUNNABLE/WAITING?
In case the idle threads are in RUNNABLE state, how are the new tasks attached to idle threads? AFAIK we assign a runnable/callable object to thread/pool. But my question is how does ThreadPoolExecutor assign queued runnable objects to idle thread??
It's easy enough to find out:
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.io.IOException;
public class ThreadExample {
public static void main(String[] args) throws IOException {
Executor executor = Executors.newFixedThreadPool(5);
// force the threads to be started
for (int i = 0; i < 5; i++) {
executor.execute(() -> {
try {Thread.sleep(1000);} catch (InterruptedException e) {
}
});
}
// don't terminate
System.in.read();
}
}
Run it:
$ javac ThreadExample.java
$ java ThreadExample
In another console, having waited at least one second for the tasks to complete:
$ ps
PID TTY TIME CMD
3640 ttys000 0:00.25 -bash
5792 ttys000 0:00.15 java ThreadExample
5842 ttys001 0:00.05 -bash
$ jstack 5792
...
"pool-1-thread-1" #12 prio=5 os_prio=31 cpu=1.77ms elapsed=13.37s tid=0x00007fe99f833800 nid=0xa203 waiting on condition [0x00007000094b2000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base#11.0.2/Native Method)
- parking to wait for <0x000000061ff9e998> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(java.base#11.0.2/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base#11.0.2/AbstractQueuedSynchronizer.java:2081)
at java.util.concurrent.LinkedBlockingQueue.take(java.base#11.0.2/LinkedBlockingQueue.java:433)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base#11.0.2/ThreadPoolExecutor.java:1054)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base#11.0.2/ThreadPoolExecutor.java:1114)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base#11.0.2/ThreadPoolExecutor.java:628)
at java.lang.Thread.run(java.base#11.0.2/Thread.java:834)
...
All the pool threads are in that state.
Curious to know the state of idle thread in case of ThreadPoolExecutor. Is it in RUNNABLE/WAITING?
It will be WAITING. It is waiting (in a Queue.take() call) for a new task to appear on the work queue. In the current implementations this involves a mechanism similar to wait / notify.
Your second question is therefore moot.
However, it is worth noting the following:
No "idle" thread will ever be RUNNABLE.
In current generation HotSpot JVMs, the actual scheduling (deciding which threads get priority and assigning them a core to run on) is handled by the operating system.
In Loom JVMs (Loom is still an Incubator project), light-weight virtual threads ("fibres") are scheduled (to a native thread) by the JVM rather than the OS.
Related
I'm looking at a jstack log and this is what i see:
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2" #250 daemon prio=5 os_prio=0 tid=0x00007f9de0016000 nid=0x7e54 runnable [0x00007f9d6495a000]
java.lang.Thread.State: RUNNABLE
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
- locked <0x00000006fa818a38> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1" #249 daemon prio=5 os_prio=0 tid=0x00007f9de000c000 nid=0x7e53 waiting for monitor entry [0x00007f9d649db000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000006fa818a38> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
- locked <0x00000006fa818a38> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0" #248 daemon prio=5 os_prio=0 tid=0x00007f9de001a000 nid=0x7e52 waiting for monitor entry [0x00007f9d64a5c000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000006fa818a38> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
- locked <0x00000006fa818a38> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)
So, in this log, each of these three threads has managed to get the same lock and the bottom two threads are actually blocked waiting for the same lock.
Can someone please explain to me what this stack log means?
The last two threads are waiting to be notified by using the instance of ThreadPoolAsynchronousRunner as monitor, so the source of that will look something like this:
synchronized(asyncRunner) {
// ...
asyncRunner.wait();
// ...
}
As soon as you call wait, the synchronization on asyncRunner is "released", i.e. other parts of the application can enter a block that is synchronized on that instance. In your particular case it seems that this has happened and the first thread's wait-call returned and it's currently processing some data that comes from it. You still see multiple locked-lines in the thread-dump to show you that the code is currently within a synchronized-block but as said, the "lock" is released when calling wait.
The technique you see here as a thread-dump is quite common before the concurrent-package was added to the JDK to avoid costly thread-creations. And your thread-dump looks like this kind of implementation. Here is a simple implementation how it might look like "under the hood":
// class ThreadPoolAsynchronousRunner
private Deque<AsyncMessage> queue;
public synchronized void addAsyncMessage(AsyncMessage msg) {
queue.add(msg);
notifyAll();
}
public void start() {
for (int i = 0; i < 4; i++) {
PoolThread pt = new PoolThread(this);
pt.start();
}
}
The ThreadPoolAsynchronousRunner`` starts PoolThreads and does a notifyAll if a new message to be processed is added.
// PoolThread
public PoolThread(ThreadPoolAsynchronousRunner parent) {
this.parent = parent;
}
public void run() {
try {
while (true) {
AsyncMessage msg = null;
synchronized(parent) {
parent.wait();
if (!parent.queue.isEmpty()) {
msg = queue.removeFirst();
}
}
if (msg != null) {
processMsg(msg);
}
}
}
catch(InterruptedException ie) {
// exit
}
}
notifyAll will lead all wait-methods of all threads to return, so you have to check if the queue in the parent still contains data (sometimes wait returns even without a notification taken place, so you need this check even if not using notifyAll). If that's the case you start the processing method. You should do that outside the synchronized-block otherwise your async-processing class only processes one message at the time (unless, that's what you want - but then why run multiple PoolThread-instances?)
Only Thread-#2 has managed to get Object lock successfully and it is in RUNNABLE state. Other 2 threads, i.e., Thread-#0 and Thread-#1 are waiting for that lock to be released by Thread-#2. As long as Thread-#2 holds the lock, Thread-#0 and Thread-#1 will remain locked and will be in a state BLOCKED.
If you have access to source code, You can review that code just to ensure if locking and unlocking is done in proper order and lock has been been held only for part of code where it is necessary. Remember these 2 threads are not in WAIT state but in BLOCKED state which is a step after WAIT state and just a step before getting in to RUNNABLE state as soon as lock is available.
There is no problem observed in this log snippet. This is not a deadlock scenario yet.
What I can see and understand is that
Thread-#2 is in Runnable state and has acquired a lock on an Object
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2"
java.lang.Thread.State: RUNNABLE
Thread-#1 and Thread-#0 are waiting for that Object lock to be released and hence blocked right now.
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1"
"com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0"
java.lang.Thread.State: BLOCKED (on object monitor) at
java.lang.Object.wait(Native Method) -
waiting on <0x00000006fa818a38>
I am using javas Thread to connect via SMTP to our mailprovider as this can take some time until it finishes and I dont want the request to wait.
But it looks like the threads are not closed after they are finished.
I noticed this in the debug mode of Eclipse:
For each time I create a new Thread(), it adds one running thread, but it is not closing it (at least I assume this, as eclipse still shows Running).
This is my code:
Thread mailThread = new Thread() {
public void run() {
System.out.println("Does it work?");
try {
Transport t = session.getTransport("smtp");
t.connect("user","pass");
t.sendMessage(message,message.getAllRecipients());
t.close();
System.out.println("SENT");
return;
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
}
};
mailThread.start();
Is this working as intended? Or does Running in eclipse mean something different?
I suggest not only to use the debugger to see, to see which threads you have at a certain point in time. Debuggers might display threads which are active during a break point but should not be there under normal conditions.
It is preferrable to use the command line tool jstack to create thread dumps. This will dump all the threads in a JVM at a certain point in time.
Here are some instructions on how to use it: https://helpx.adobe.com/uk/experience-manager/kb/TakeThreadDump.html
Another thing could help you debugging and finding threads in the dump: give threads a name using the string in one of the constructor.
new Thread("foo")
Then it becomes easier to find these in the thread dump.
If you call a thread "foo" then it will show up in a thread dump like this:
"foo" #16 prio=5 os_prio=0 tid=0x0000000041970800 nid=0x41f8 waiting on condition [0x000000004244e000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(java.base#9/Native Method)
at stackoverflow.ThreadReferenceTest$1.run(ThreadReferenceTest.java:14)
Locked ownable synchronizers:
- None
"Service Thread" #15 daemon prio=9 os_prio=0 tid=0x0000000041914000 nid=0x3d90 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
I build a vehicle routing web application using optaplanner. When I tried to deploy my web application to a tomcat 8 server, and tried to run it from my web browser, it produces a warning in my tomcat log file. The log said something about my web application started a thread and failed to stop it, and probably will create a memory leak.
I have write a destroy method where my ExecutorService object will call shutdown method to make sure every thread it started was terminated. Here is my code :
public class OptimizerService implements IOptimizerService {
private ExecutorService executor;
#Override
public synchronized Boolean startSolving() throws Throwable {
executor = Executors.newFixedThreadPool(2);
...
}
...
// other methods
...
#PreDestroy
public synchronized void destroy() {
executor.shutdown();
}
}
But why I still got those warning in tomcat log?
Here is the tomcat log :
09-Jun-2017 08:25:56.377 WARNING [http-nio-18081-exec-295] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [VehicleRouting] appears to have started a thread named [drools-worker-4] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Any comment will be appreciated. Thanks and regards.
executor.shutdownNow(); interrupts the threads, but executor.shutdown(); does not. That latter just waits until the tasks are finished, good luck if you have a 2h solver running...
If the Solver detects that its thread is interrupted, it terminates (pretty much the same as a normal Termination), which in turns calls KieSession.dispose(). I presume dispose() takes care of any drools spawned threads.
That's the theory at least :)
Recently I was asked a question:
We've got the setPriority() method to set a thread for low priority.
Then why do we need a daemon thread. What's the difference between them?
Does marking a thread as daemon change its scheduling?
We've got the setPriority() method to set a thread for low priority. Then why do we need a daemon thread. What's the difference between them?
Typically, daemon threads have nothing to do with priority. The JVM shuts down when all user non-daemon threads finish. Marking a thread as a daemon thread means that it can be safely killed when the JVM exits.
Priority is about scheduling – about how often a thread gets a time slice in comparison to other threads that are ready to run. You can have low priority daemon threads or high priority daemon threads. You can have non-daemon threads that are also low and high priority. As an aside, thread priorities only apply in certain specific situations and on certainly architectures and as a Java thread expert, I never use them.
The concepts are orthogonal (mutually independent) – at least in the Java thread model.
In terms of when to make a thread daemon, I use daemon threads for any tasks that I don't care if they are interrupted when the JVM quits: keep-alive threads, statistics processors, log handling, etc.. Everything mission critical to the application is a non-daemon thread that has to be specifically interrupted or signaled to quit somehow.
A running daemon thread will not prevent your program from ending/exiting. However, all user threads must end before your program can exit. Priority may apply to either daemon or user thread. You may understand priority the same way you understand it in everyday life.
An example of
JVM shutting down when low priority thread completes. Despite Daemon threads still running
ALSO, shows that thread created by a daemon thread automatically becomes a daemon thread
package junk.daemon_thread_example;
class DeamonThreadPlus implements Runnable{
String id;
boolean createChild;
public DeamonThreadPlus(String id, boolean createChild){
this.id = id;
this.createChild = createChild;
}
#Override
public void run() {
// Parent daemon thread creates child daemon thread by default
if (createChild)
new Thread(new DeamonThreadPlus("DaemonChild", false)).start();
// This thread never self-completes (only terminates when process dies)
while (true){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Daemon "
+ Thread.currentThread().isDaemon()
+ " id = " + id);
}
}
}
class UThread implements Runnable{
#Override
public void run() {
System.out.println("User thread start");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("User thread end (program exits)");
}
}
public class Caller{
public static void main(String[] args) {
Thread dt = new Thread( new DeamonThreadPlus("Daemon", true));
dt.setDaemon(true);
dt.start();
Thread ut = new Thread(new UThread());
ut.setPriority(Thread.MIN_PRIORITY);
ut.start();
}
}
The output is:
User thread start
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
User thread end (program exits)
Daemon true id = DaemonChild
Daemon true id = Daemon
If the Java runtime determines that the only threads running in an application are daemon threads (i.e., there are no user threads in existence) the Java runtime promptly closes down the application, effectively stopping all daemon threads dead in their tracks. In order for an application to continue running, it must always have at least one live user thread. In all other respects the Java runtime treats daemon threads and user threads in exactly the same manner.
except that in daemon thread .. when JVM terminate abruptly then finally blocks are not executed, stacks are not unwound – JVM just exits. Due to this reason daemon threads should be used sparingly and it is dangerous to use them for tasks that might perform any sort of I/O.
i have been try to use the LMAX distruptor to buffer the content produced by one of my programs and publish them to another program as a batch of records (well i am still unable to get the consumer batching part done). But even without using the batching of the records, it works as it should be. But my problem is eventhough i used call the
`disruptor.shutdown()` and `executorService.shutdownNow()`
as it is given in one of the examples, it doesn't stop executing the program. It does even execute statement below those methods as well. When i print
executorService.isShutdown();
it returns true. Can someone help me with this...
Edit
"pool-1-thread-1" prio=10 tid=0x00007f57581b9800 nid=0x1bec waiting on condition [0x00007f573eb0d000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d9110148> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:45)
at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:55)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Some tips that help me:
1. Set daemon flag on ExecutorService threads
Do this with a ThreadFactory (or Guava's ThreadFactoryBuilder).
Example:
final ThreadFactory threadFactory =
new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
final ThreadFactory threadFactory = Executors.defaultThreadFactory();
final Thread thread = threadFactory.newThread(r);
thread.setDaemon(true);
return thread;
}
};
final ExecutorService executorService =
Executors.newFixedThreadPool(threadCount, threadFactory);
2. Shutdown order
Disruptor.shutdown(long, TimeUnit)
Disruptor.halt()
ExecutorService.shutdown()
ExecutorService.awaitTermination(long, TimeUnit)
Impatient shutdown example:
try {
disruptor.shutdown(0, TimeUnit.NANOSECONDS);
// if shutdown is successful:
// 1. exception is not thrown (obviously)
// 2. Disruptor.halt() is called automatically (less obvious)
}
catch (TimeoutException e) {
disruptor.halt();
}
executorService.shutdown();
executorService.awaitTermination(0, TimeUnit.NANOSECONDS);
3. Use a Shutdown Hook
These are called even when System.exit(int) is called, but not if your JVM is killed with SIGKILL (or the equivalent on non-POSIX platforms).
Runtime.getRuntime()
.addShutdownHook(
new Thread(
() -> {
// shutdown here
}));
Your Java Process only stops, when all threads (that are non daemon threads) are finished.
Probably some thread is still running, maybe in a lock, maybe in a loop.
To see what thread are still running you can use the jdk-tools:
Use jps to get the ids of running Java processes:
C:\DVE\jdk\jdk8u45x64\jdk1.8.0_45\bin>jps
4112 TestExMain
With the right id for your program use the command jstack:
C:\DVE\jdk\jdk8u45x64\jdk1.8.0_45\bin>jstack 4112
2015-09-17 09:12:45
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode):
"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001d208800 nid=0x1b7c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"main" #1 prio=5 os_prio=0 tid=0x0000000002260800 nid=0x1324 waiting on condition [0x000000000224f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.example.TestExMain.main(TestExMain.java:8)
For example, here you'll see a thread Service Thread which is a daemon - this thread wont stop your program from shutting down.
The Thread main is not a daemon thread - the Java-Process will wait for this thread to finish, before it stops.
For each thread you'll see a stack trace, at which position the thread is - with that you can find the code that possible keeps the thread from running.
That specific Thread you have there is somehow locked (im not shure why, it could be a wait() call, a synchronize block or some other locking mechanism). When that thread doesn't stop when you call disruptor.shutdown() it might be a bug in that lib you use.