i've got an application with a possible number of threads. basicly the threads should work this:
Main Thread
CalculationThread
CalculationThread
CalculationThread
Adding / Executing those threads to a FixedThreadPool isn't the problem. The Thread itself calls a certain function in the Mainthread to submit the results. After this step, the thread should sleep until it will be called again for the next calucation.
The Mainthread holds a reference to a CalculationThread to submit updates to the thread and readd it to the pool to start the next calculation.
My Problem: How can I enforce a timeout for a certain thread? The enforcement of this timeout must also work, if a endless loop occurs
You cannot enforce the timeout without cooperation from the thread, at least not in a sane way. You should code your calculation tasks so that they comply with the Java interruption mechanism. Basically, that means occasionally checking the Thread.interrupted return value and aborting on true.
The only other option is the ham-handed – and deprecated – Thread.stop, which can wreak general chaos, especially when done on a pool-managed thread.
Related
This question already has answers here:
How do you kill a Thread in Java?
(17 answers)
Closed 2 years ago.
I want to create a thread to judge user code:
FutureTask<Integer> futureTask = new FutureTask(() -> run(type)); // run is a method
Thread thread = new Thread(futureTask);
thread.start();
As we all known, an infinite loop may be written in the user code, so the method run will be working all the time and the Thread thread will not stop. I want to terminate this thread after timeout duration. How can I terminate it instead of using Thread.stop because it's unsafe?
The correct way to deal with a thread that needs to be stopped is to design the thread's code so that it responds appropriately to being interrupted:
Long computations need to occasionally check the current thread's "interrupted" flag.
InterruptedException should be handled appropriately.
The thread application code's response to the interrupt should be to gracefully stop what it is doing1 and (typically) allow the thread to terminate.
(You could also use a custom flag implemented using a volatile shared variable instead of the interrupted flag. However, that doesn't deal with interrupting wait, sleep and similar operations, and is therefore a poor substitute for interrupts.)
The unsafe way is to call the deprecated Thread.stop() method. (The javadocs explain why it is unsafe, and we don't need to repeat that here.)
The (related) Thread.stop(Throwable) method was removed in Java 11; see:
Java 11 Removes stop() and destroy() Methods.
https://bugs.openjdk.java.net/browse/JDK-8204243
Unfortunately, there is nothing in between these two approaches for interrupting a thread.
If you cannot get your long running thread to cooperate, the safe alternative would be to run it in a separate process; e.g. using System.ProcessBuilder etcetera to run the java command. The (external) process could then be killed if it took too long. The downsides include:
An external process cannot access the current JVM's variables, etcetera. So you need to use a different mechanism to pass information between the parent and child processes.
Starting a new JVM is a lot more expensive than starting a new thread.
1 - For example, if the thread owns resources such as open files or sockets, it should release them. If it is performing an action for some other thread that will be waiting for the result, it should signal (in the appropriate way) that there will be no result. And so on.
Terminating thread from outside is ALWAYS unsafe and very strongly discouraged. You need to notify the thread that you want it to terminate and the thread must do it itself. That is done with method interrupt() of the class Thread. In your example it would be from the main code to call thread.interrupt() That will cause the interrupt flag to be raised in your thread. In your run method of your thread you should check for that flag (See methods interrupted() and isInterrupted() in the class Thread). Once you see that your flag is raised, break out of the loop and finish the method. That will stop your thread.
Could you explain me, why in ScheduledThreadPoolExecutor javadoc is this:
Additionally, it is almost never a good idea to set corePoolSize to
zero or use allowCoreThreadTimeOut because this may leave the pool without
threads to handle tasks once they become eligible to run.
I've tried to analyze how new threads are created in this thread pool when a new task has to be executed and I think problem described in javadoc shouldn't happen.
The thread pool trys to make the number of work threads equals corePoolSize, to improve efficiency by caching threads. Allowing core thread time out is contrary to this purpose. If you allow core thread time out, new task will be executed, but leads to repeatly create and destroy work threads.
If you set allowCoreThreadTimeOut = true, then after the work thread find no task in task queue and time out, they will be destroyed even the number of working threads is less than corePoolSize. So, if you submit new task at this time, the thread pool has to create new thread.
If you set allowCoreThreadTimeOut = false, then after the work thread find no task in task queue and number of work threads less than corePoolSize, they will be not be destroyed and keep waiting for new task.
My guess is that the answer is stale Javadoc, for the most part. As you note, ensurePrestart ensures that as long as corePoolSize > 0, the number of core pool threads is nonzero after the call. This has been the case since https://github.com/openjdk/jdk/commit/2d19ea519b17529a083a62eb219da532693bbef3, but notably that commit did not update the Javadoc on ScheduledThreadPoolExecutor.
However, the details aren't quite so simple either. Rather than only worrying about new task submissions and task reschedule on completion, you also need to worry about core pool threads idling out because all scheduled tasks are too far in the future to trigger before the pool timeout.
Not sure if I'm reading the JRE code correctly, but it looks like in such a case, the pool will:
Start a worker thread (due to ensurePrestart)
Regardless of thread type (core or not), the thread is eligible for timeout because allowCoreThreadTimeout is true
Worker thread polls DelayedWorkQueue for next task, with timeout
poll returns null (times out), because the next scheduled task is beyond pool timeout
The core thread will terminate because it thinks there is nothing to do
ThreadPoolExecutor.processWorkerExit will run on worker termination. It will check the queue, notice that it's nonempty, and thus require a minimum of at least one thread
If the thread being terminated is the last thread, it will notice that the minimum is not met and immediately start a new (non-core) worker
Repeat from step 1
So, the pool will work as you intend, but probably won't be in an ideal state either (you really want a single core thread polling without timeout here, not threads constantly spinning up, polling with timeout, timing out, then starting a new thread to replace itself). In that sense, step 6 is really what prevents the case mentioned in Javadoc (by the time tasks are eligible, all pool threads have timed out), but it does so imperfectly because of the unnecessary thread creation/destruction loop.
This weirdness is really because DelayedWorkQueue semantically breaks the BlockingQueue contract. All else equal, you'd assume that size() > 0 implies that a subsequent poll(...) will successfully retrieve an element and not time out, but DelayedWorkQueue allows those elements to be held back for some time (even though they're already visible via size() and isEmpty()).
NOTE: Seems like this code changed in Java 8, with the addition of this condition to ThreadPoolExecutor.getTask(). This will keep that last worker thread alive and avoid the thread create/destroy loop, but it will busy-poll the work queue for work instead.
So far what I have understood about wait() and yield () methods is that yield() is called when the thread is not carrying out any task and lets the CPU execute some other thread. wait() is used when some thread is put on hold and usually used in the concept of synchronization. However, I fail to understand the difference in their functionality and i'm not sure if what I have understood is right or wrong. Can someone please explain the difference between them(apart from the package they are present in).
aren't they both doing the same task - waiting so that other threads can execute?
Not even close, because yield() does not wait for anything.
Every thread can be in one of a number of different states: Running means that the thread is actually running on a CPU, Runnable means that nothing is preventing the thread from running except, maybe the availability of a CPU for it to run on. All of the other states can be lumped into a category called blocked. A blocked thread is a thread that is waiting for something to happen before it can become runnable.
The operating system preempts running threads on a regular basis: Every so often (between 10 times per second and 100 times per second on most operating systems) the OS tags each running thread and says, "your turn is up, go to the back of the run queue' (i.e., change state from running to runnable). Then it lets whatever thread is at the head of the run queue use that CPU (i.e., become running again).
When your program calls Thread.yield(), it's saying to the operating system, "I still have work to do, but it might not be as important as the work that some other thread is doing. Please send me to the back of the run queue right now." If there is an available CPU for the thread to run on though, then it effectively will just keep running (i.e., the yield() call will immediately return).
When your program calls foobar.wait() on the other hand, it's saying to the operating system, "Block me until some other thread calls foobar.notify().
Yielding was first implemented on non-preemptive operating systems and, in non-preemptive threading libraries. On a computer with only one CPU, the only way that more than one thread ever got to run was when the threads explicitly yielded to one another.
Yielding also was useful for busy waiting. That's where a thread waits for something to happen by sitting in a tight loop, testing the same condition over and over again. If the condition depended on some other thread to do some work, the waiting thread would yield() each time around the loop in order to let the other thread do its work.
Now that we have preemption and multiprocessor systems and libraries that provide us with higher-level synchronization objects, there is basically no reason why an application programs would need to call yield() anymore.
wait is for waiting on a condition. This might not jump into the eye when looking at the method as it is entirely up to you to define what kind of condition it is. But the API tries to force you to use it correctly by requiring that you own the monitor of the object on which you are waiting, which is necessary for a correct condition check in a multi-threaded environment.
So a correct use of wait looks like:
synchronized(object) {
while( ! /* your defined condition */)
object.wait();
/* execute other critical actions if needed */
}
And it must be paired with another thread executing code like:
synchronized(object) {
/* make your defined condition true */)
object.notify();
}
In contrast Thread.yield() is just a hint that your thread might release the CPU at this point of time. It’s not specified whether it actually does anything and, regardless of whether the CPU has been released or not, it has no impact on the semantics in respect to the memory model. In other words, it does not create any relationship to other threads which would be required for accessing shared variables correctly.
For example the following loop accessing sharedVariable (which is not declared volatile) might run forever without ever noticing updates made by other threads:
while(sharedVariable != expectedValue) Thread.yield();
While Thread.yield might help other threads to run (they will run anyway on most systems), it does not enforce re-reading the value of sharedVariable from the shared memory. Thus, without other constructs enforcing memory visibility, e.g. decaring sharedVariable as volatile, this loop is broken.
The first difference is that yield() is a Thread method , wait() is at the origins Object method inheritid in thread as for all classes , that in the shape, in the background (using java doc)
wait()
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
yield()
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
and here you can see the difference between yield() and wait()
Yield(): When a running thread is stopped to give its space to another thread with a high priority, this is called Yield.Here the running thread changes to runnable thread.
Wait(): A thread is waiting to get resources from a thread to continue its execution.
I have been reading a lot on this but I am not sure what's the most elegant way of handling my usecase. I have an application that starts a background scheduled thread using ScheduledThreadPoolExecutor. This scheduled thread in-turn has an ExecutorService of pool size 20. Each new thread submitted to this pool will inturn again have an ExecutorService of pool size, lets say 50. The lowest level thread doesn't do much other than looping through some standard tasks, each task taking anywhere from a second to 10 seconds.
As this is a background agent application performing background tasks, We should be able to stop them cleanly any time we want. The problem is I am not sure how to trickle down the an interuption/shutdown signal 3 level down to the lowest thread so I can break out of the loop and shutdown all the threads neatly.
I was looking into Runtime.addShutdownHook() but I wasn't exactly sure how it will be useful in my usecase. I was also looking into checking for isInterrupted() at the lowest possible Thread level but than I wasn't sure if Ctrl + C or kill -9 / kill -15 command actually is transformed to an interrupted signal inside the application. And if so, how would it trickle down 3 levels of threads, or would I have to manually interrupt each thread inside the Runtime.addShutdownHook().
I am trying to find a solution that is most elegant and safe.
The interrupted flag has nothing to do with native OS-level signals sent to the process hosting the JVM. You can set the interrupted flag on any thread by calling thread.interrupt().
For your problem I would suggest accumulating all your ExecutorServices into a global collection so that you may call shutdownNow() on each upon termination. If you use a gentle-enough signal to terminate your process, the shutdown hooks should be executed and there you can try to shut down your executor services. Note, however, that each task you submit must be interruptible, which means that it must respoond to the setting of the interrupted flag by actually finishing its work. This will not happen implicitly.
I must add that I find your solution with numerous executor services quite odd. A single, properly configured thread pool should be all you need in addition to the scheduled executor.
I have a confusion. I read somewhere that Thread.yield() method causes the currently running thread to pause and give chance to remaining thread of "Same Priority".
Now always it is same priority threads executed or higher priority threads can also be executed. And if suppose currently running thread has some lock on some object, after executing yeild method will it give its lock?
When you call Thread.yield() the current thread pauses and allows the scheduler to run a different thread. Priorities are managed by the scheduler.
And no, of course not - you don't release any locks. Doing so would break synchronization.