Why is there no "awaitTermination(Date deadline)" method? - java

I have a list of tasks submitted to an ExecutorService. But I need to shutdown the ExecutorService before a deadline of 2:30AM, even if the tasks are not finished. How can I achieve this? I checked the API, there is only a method like below:
ExecutorService exec = //...
exec.awaitTermination(100, TimeUnit.MILLISECONDS);
But how can I make the following block executing atomically? That is, how can I avoid the gap? For example:
long timeDiff= calculate(now, deadline);
// Gap: assuming current thread does not have chance to run for 10 minutes...
exec.awaitTermination(timeDiff, TimeUnit.MILLISECONDS);
Thanks.

You probably don't mean 'atomically', I think you mean 'without delay' here. So that timeDiff is still correct when calling exec.awaitTermination().
I assume that's correct, so the answer is: you can't.
If you're interested in the details:
Your Java Code gets translated to Java Bytecodes and these get executed by the JVM which is a regular process running on your operating system. And you simply can't stop the operating system from interrupting threads (I assume you use a operating system with preemptive multitasking (every UNIX (including Linux and Mac OS X), Windows 95 or better, ...)).
Even if you could do all that in one Java Bytecode it would still not work as you want it to because the operating system could interrupt you in the middle of one Java Bytecode.
And even a awaitTermination(Date deadline) method wouldn't help here. It has to be implemented by someone, too.
The best you can do is to do it in as few bytecodes as possible.
If I were you, I'd probably do just as your code does it.
However, that could be a bit more precise:
Date deadline = ....;
final TimerTask stopTask = new TimerTask() {
public void run() {
exec.shutdownNow();
}
};
new Timer().schedule(stopTask, deadline);
But as I said: There is no real guarantee shotdownNow() gets executed IMMEDIATELY at deadline. In reality, setting deadline to one second before the real deadline should be okay :-)

Wait deadline in another high priority thread (or timer) and call exec.shutdownNow()

Related

Does it make sense to use an executor for one thread with a hard limit guarantee?

I need to have a background thread that constantly does an action, sleep for X seconds and do the action etc.
Basically the run method is something like:
while(!isInterrupted()){
//do something
Thread.sleep(10);
}
My question is:
Does it make sense to use an executor in this case? Since I am not
spawning threads, is even in this case using an executor (single
threaded) better?
Additionally if I want a guarantee that the thread goes in the do
something part in exactly 10 seconds, is that possible via using
just a custom thread or more guaranteed via an executor? I mean if I have a hard limit of 10 seconds to perform an action, what can I do to achieve it? I assume that the time that the code goes back in do something may fluctuate due to scheduling etc. How could I get such a guarantee?
If you are using only a single thread which is a forever running task like yours then you can use your present logic.
But only when you have some small tasks that need to be run, then there is point in using SingleThreadPool.
How could I get such a guarantee?
There is no such guarantee from the OS side (Linux or Windows), that the thread will return from sleep at exact 10 seconds. Try increasing thread priority, but that too is not guaranteed to work.
Your logic should not be dependent on such hard timings IMO.

Will a thread in a while loop give CPU time to another thread of same type?

If I have the following dummy code:
public static void main(String[] args) {
TestRunnable test1 = new TestRunnable();
TestRunnable test2 = new TestRunnable();
Thread thread1 = new Thread(test1);
Thread thread2 = new Thread(test2);
thread1.start();
thread2.start();
}
public static class TestRunnable implements Runnable {
#Override
public void run() {
while(true) {
//bla bla
}
}
}
In my current program I have a similar structure i.e. two threads executing the same Run() method. But for some reason only thread 1 is given CPU time i.e. thread 2 never gets a chance to run. Is this because while thread 1 is in its while loop , thread 2 waits?
I'm not exactly sure, if a thread is in a while loop is it "blocking" other threads? I would think so, but not 100% sure so it would be nice to know if anyone could inform me of what actually is happening here.
EDIT
Okay, just tried to make a really simple example again and now both threads are getting CPU time. However this is not the case in my original program. Must be some bug somewhere. Looking into that now. Thanks to everyone for clearing it up, at least I got that knowledge.
There is no guarantee by the JVM that it will halt a busy thread to give other threads some CPU.
It's good practice to call Thread.yield();, or if that doesn't work call Thread.sleep(100);, inside your busy loop to let other threads have some CPU.
At some point a modern operating system will preempt the current context and switch to another thread - however, it will also (being a rather dumb thing overall) turn the CPU into a toaster: this small "busy loop" could be computing a checksum, and it would be a shame to make that run slow!
For this reason, it is often advisable to sleep/yield manually - even sleep(0)1 - which will yield execution of the thread before the OS decides to take control. In practice, for the given empty-loop code, this would result in a change from 99% CPU usage to 0% CPU usage when yielding manually. (Actual figures will vary based on the "work" that is done each loop, etc.)
1The minimum time of yielding a thread/context varies based on OS and configuration which is why it isn't always desirable to yield - but then again Java and "real-time" generally don't go in the same sentence.
The OS is responsible for scheduling the thread. That was changed in couple of years ago. It different between different OS (Windows/Linux etc..) and it depends heavily on the number of CPUs and the code running. If the code does not include some waiting functionality like Thread.yield() or synchhonized block with a wait() method on the monitor, it's likely that the CPU will keep the thread running for a long time.
Having a machine with multiple CPUs will improve your parallelism of your application but it's a bad programming to write a code inside a run() method of a thread that doesn't let other thread to run in a multi-threaded environment.
The actual thread scheduling should be handled by the OS and not Java. This means that each Thread should be given equal running time (although not in a predictable order). In your example, each thread will spin and do nothing while it is active. You can actually see this happening if inside the while loop you do System.out.println(this.toString()). You should see each thread printing itself out while it can.
Why do you think one thread is dominating?

How to ensure a Thread won't delay in Java?

I wrote a multi threading programme, which have two to four thread at the same time.
One of the thread is time critical thread, it will be called every 500 milliseconds, it is not allow to delay more than 10 milliseconds. But when other thread have more loading, I find that some delay, around two millisecond is occurred. (Print the timestamp to show it) So, I worry that after running for a long time it will delay more than 10 milliseconds, except from check the timestamp, and adjust the looping interval to make sure the time is not delay more than 10 milliseconds, is there any way to make it safe?
Thanks.
Sounds like you need Real-Time Java
If timing is critical, I use a busy wait on a core which is dedicated to that thread. This can give you << 10 micro-second jitter most of the time. Its a bit extreme and will result in the logical thread not being used for anything else.
This is the library I use. You can use it to reserve a logical thread or a whole core. https://github.com/peter-lawrey/Java-Thread-Affinity
By using isolcpus= in grub.conf on Linux you can ensure that the logical thread or core is not used for any else (except the 100 Hz timer and power management which are relatively small and < 2 us delay)
You can set your threads priorities:
myCriticalThread.setPriority(Thread.MAX_PRIORITY);
otherThread.setPriority(Thread.NORM_PRIORITY); // the default
yetAnotherThread.setPriority(Thread.MIN_PRIORITY);
It won't really guarantee anything though.
There is no guarantee that your thread isn't delayed, because the OS may decide to give other processes precedence (unless you put effort in setting up a complete real-time system including a modified OS). That being said, for basic tasks, you should use a ScheduledExecutorService like this:
class A {
private final ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
public void startCriticalAction(Runnable command) {
this.exe.scheduleAtFixedRate(command, 100, 100, TimeUnit.MILLISECONDS);
}
public void shutdown() {
this.exe.shutdown();
}
}
The executor service will do its best to execute the task every 100ms. You should not develop this functionality yourself, because a lot of things can go wrong.
Creep up on the timeout:
waitFor(int timeout)
{
dateTime wallTimeEnd;
wallTimeEnd=now()+(msToDateTime(timeout));
int interval=timeout/2;
while(true){
if(interval>10){
sleep(interval);
interval=dateTimeToMs(wallTimeEnd-now()) / 2;
}
else
{
do{
sleep(0);
interval=dateTimeToMs(wallTimeEnd-now());
}while(interval>0);
}
}
This only wastes a core for 5-10ms

Java performance issue with Thread.sleep()

Inline Java IDE hint states, "Invoking Thread.sleep in loop can cause performance problems." I can find no elucidation elsewhere in the docs re. this statement.
Why? How? What other method might there be to delay execution of a thread?
It is not that Thread.sleep in a loop itself is a performance problem, but it is usually a hint that you are doing something wrong.
while(! goodToGoOnNow()) {
Thread.sleep(1000);
}
Use Thread.sleep only if you want to suspend your thread for a certain amount of time. Do not use it if you want to wait for a certain condition.
For this situation, you should use wait/notify instead or some of the constructs in the concurrency utils packages.
Polling with Thread.sleep should be used only when waiting for conditions external to the current JVM (for example waiting until another process has written a file).
It depends on whether the wait is dependent on another thread completing work, in which case you should use guarded blocks, or high level concurrency classes introduced in Java 1.6. I recently had to fix some CircularByteBuffer code that used Thread sleeps instead of guarded blocks. With the previous method, there was no way to ensure proper concurrency. If you just want the thread to sleep as a game might, in the core game loop to pause execution for a certain amount of time so that over threads have good period in which to execute, Thread.sleep(..) is perfectly fine.
It depends on why you're putting it to sleep and how often you run it.
I can think of several alternatives that could apply in different situations:
Let the thread die and start a new one later (creating threads can be expensive too)
Use Thread.join() to wait for another thread to die
Use Thread.yield() to allow another thread to run
Let the thread run but set it to a lower priority
Use wait() and notify()
http://www.jsresources.org/faq_performance.html
1.6. What precision can I expect from Thread.sleep()?
The fundamental problem with short sleeps is that a call to sleep finishes the current scheduling time slice. Only after all other threads/process finished, the call can return.
For the Sun JDK, Thread.sleep(1) is reported to be quite precise on Windows. For Linux, it depends on the timer interrupt of the kernel. If the kernel is compiled with HZ=1000 (the default on alpha), the precision is reported to be good. For HZ=100 (the default on x86) it typically sleeps for 20 ms.
Using Thread.sleep(millis, nanos) doesn't improve the results. In the Sun JDK, the nanosecond value is just rounded to the nearest millisecond. (Matthias)
why? that is because of context switching (part of the OS CPU scheduling)
How? calling Thread.sleep(t) makes the current thread to be moved from the running queue to the waiting queue. After the time 't' reached the the current thread get moved from the waiting queue to the ready queue and then it takes some time to be picked by the CPU and be running.
Solution: call Thread.sleep(t*10); instead of calling Thread.Sleep(t) inside loop of 10 iterations ...
I have face this problem before when waiting for asynchronous process to return a result.
Thread.sleep is a problem on multi thread scenario. It tends to oversleep. This is because internally it rearrange its priority and yields to other long running processes (thread).
A new approach is using ScheduledExecutorService interface or the ScheduledThreadPoolExecutor introduce in java 5.
Reference: http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html
It might NOT be a problem, it depends.
In my case, I use Thread.sleep() to wait for a couple of seconds before another reconnect attempt to an external process. I have a while loop for this reconnect logic till it reaches the max # of attemps. So in my case, Thread.sleep() is purely for timing purpose and not coordinating among multithreads, it's perfectly fine.
You can configure you IDE in how this warning should be handled.
I suggest looking into the CountDownLatch class. There are quite a few trivial examples out there online. Back when I just started multithreaded programming they were just the ticket for replacing a "sleeping while loop".

What is the correct way to perform long-running operation outside the EDT?

In a desktop Java 1.5 application (it has to run on a lot of MacOS X machines that will nerver see a 1.6 VM due to Apple politics) what is a correct way to perform a lengthy computation outside the EDT?
Say, for example, when the user clicks on a button that starts an operation: I get the notification on the EDT and I want to run some method (say crunchData()).
Here's one way to do it:
final Thread t = new Thread( new Runnable() {
public void run() {
crunchData();
}
} );
t.start;
I mean: this does what I want but every single time the user starts a potentially long running task I use the above idiom. And I feel like I'm always unnecessarily creating lots of task (moreover although sometimes the operation can be lengthy, sometimes it won't and in these case I'd like the app as responsible as possible).
Another way to do it would be to have another (non-EDT) thread (or a pool of threads), always running, say waiting on a blocking queue and executing, say, Runnable that I would enqueue wherever I need to perform a lengthy operation.
What is the correct way to deal with this?
EDIT: Is the correct way to deal with something that simple to install SwingWorker? How did people deal with this (which seems pretty basic) before SwingWorker came?
The recommended way is to have your EDT code start a SwingWorker, which will do the job outside and return the result to you.

Categories

Resources