Java Wake Sleeping Thread - java

I did some reading of other post but didn't find an exact answer to what I'm looking for, so I hope someone can give some some clarification.
I have a program that will run for some time. I have some threads that run in the back ground that perform various tasks, to keep things simple let think of 3 threads. ThreadA performs a task every 10 seconds, where ThreadB does something every 30 seconds and ThreadC does something every 5 mintues.
I don't use busy waiting, and put the threads to sleep for the designated times.
My question is regarding a clean shut down. I have a variable that each of the threads have read access too, so they can see when the user initiates the exit of the program. The next time the threads are active, they exit their loops and join and all is good. But you can see that ThreadC only wakes up every 5 minutes.
The question I have is can I signal the sleeping threads to wake up and exit before their sleep time is over? If this is not possible, do I need to rework the code to use wait() and notify() or is there a better way?

Thread.sleep throws InterruptedException if the thread is interrupted during the sleep. Catch that, and check your flag.

If the threads are sleeping with Thread.sleep(...), you can wake them up with Thread.interrupt(). Make sure you're handling the InterruptedException and testing Thread.currentThread().isInterrupted() in your loops.

You can call the interrupt() method on your thread and will make your Thread go to running state from block state, but it will throw an exception which is InterruptedException which by then you can shutdown your thread in the catch block
Also other solution is that you can use the Timer Task that will call the run method on a certain time you specified without putting your Thread to the block state
example:
public class TimerBomb {
Toolkit toolkit;
Timer timer;
int count = 0;
public TimerBomb(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(), seconds * 1000, seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
//do stuff here
}
}
public static void main(String args[]) {
System.out.println("About to schedule task.");
Thread t = new Thread(new Runnable() {
#Override
public void run() {
new TimerBomb(5);
}
});
t.start();
System.out.println("Task scheduled.");
}
}
It will run every 5 second forever.

You should look into ExecutorService and its shutdownNow() method (which generally interrupts all the active threads). You sense reinventing the scheduling wheel.

All of the other answers are good answers to the question that you actually asked, but none of them gives the best answer to the question that you should have asked. The question is, what's the best way to schedule several periodic tasks that must recur with different periods? The answer is, use a java.util.concurrent.ScheduledExecutorService.
Like all ExeuctorServices, it provides methods, shutdown() and shutdownNow(), for when you want the tasks to stop.

Related

How to preserve thread-safety of a CopyOnWriteArrayList with a correct run() method implementation?

I am using an ExecutorService with a fixedThreadPool. I create threads by implementing the Runnable interface. In the run() method, I am calling a time consuming function (let's say Thread.sleep() for now) and finally add an element to a thread safe CopyOnWriteArrayList. I am submitting threads in a for-loop. At the end of the for-loop I shutdown the ExecutorService and await termination.
However, the number of elements in the list does not turn out to be the same as the number of loop-iterations. Where is my mistake in concurrency thinking?
Here is a code example for this problem:
public class TestProgram {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(4);
CopyOnWriteArrayList<String> stringList = new CopyOnWriteArrayList<String>();
for (int i = 0; i < 1000; i++) {
executor.submit(new myThread(stringList));
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
System.out.println(Integer.toString(stringList.size()));
}
}
class myThread implements Runnable {
CopyOnWriteArrayList<String> stringList;
public myThread(CopyOnWriteArrayList<String> stringList) {
this.stringList = stringList;
}
public void run() {
String string = new String("test");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(myThread.class.getName()).log(Level.SEVERE, null, ex);
}
stringList.add(string);
}
}
You're just not giving it enough time to complete. If you want to execute this serially you would need 1000 * 100 milliseconds, which is 100 seconds. You are running it with four threads, so divide that by 4 and you get 25 seconds. You only wait 10 seconds to complete. Increase that to 26 seconds just to be safe and you should see your result.
The ExecutorService#awaitTermination will wait the N number of seconds to complete, if it doesn't complete it will simply return out and continue the execution. To prove my point check the return value
System.out.println(executor.awaitTermination(10, TimeUnit.SECONDS));
The better solution here, is to use a new CountDownLatch(1000), have each Runnable task countDown after it adds to the list and finally have the main thread await completion.
The documentation of ExecutorService.shutdown says the following:
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted. Invocation has no
additional effect if already shut down.
This method does not wait for previously submitted tasks to complete
execution. Use awaitTermination to do that.
This means that you indicate your ExecutorService that it must stop it's services. Thus, this method sets a flag which indicates that the ExecutorService will end soon, which allows the main thread to returns from this method without problems.
ExecutorService.awaitTermination, moreover, reads as follows:
Blocks until all tasks have completed execution after a shutdown
request, or the timeout occurs, or the current thread is interrupted,
whichever happens first.
This means that the main thread will be blocked inside the method, where it will only be returned when the tasks sent to ExecutorService finish. In both cases, the developer intends to end the ExecutorService function. But with awaitTermination, the developer is saying ExecutorService should be terminated regardless of their tasks have been carried out or not.
As each task takes at least 100 milliseconds to complete, no one will possibly be completed because ExecutorService has a tolerance of only 10 milliseconds for completion of all it's tasks.
There is no point in calling shutdown and awaitTermination at the same time (or preceded by another). According to your code, shutdown has no effect. If you want your tasks to become completed, and that ExecutorService is terminated without caring if your main thread will continue, just use shutdown. If you do not want your main thread to be blocked, and simply want to end with ExecutorService, use shutdownNow.
If, on the other hand, you want your main thread to wait for the execution of your tasks without a certain time to be specified, you may have to use Java Synchronizers. Some of Java Synchronizers are as follow:
Latches
FutureTasks
Semaphores
Barriers
For your case, I believe you can use CountDownLatch. Make a new CountDownLatch object have the number of tasks running on your ExecutorService. As they are completed, the count is decreased, and so, your main thread can expect completion and continue after all.
I hope you have understood and you can do what you want. If you have further questions, the documentation of CountDownLatch demonstrates perfectly how you can synchronize tasks. Good luck.
In that code snippet one issue will be there.
executor.awaitTermination(10, TimeUnit.SECONDS);
Here it will wait for 10 seconds after that it will break.
You will try following snippet.
while (true) {
if(executor.awaitTermination(10, TimeUnit.SECONDS))
break;
}

Java: How to pause 1 class from running?

when I use Thread.sleep();, it pauses my entire program. Is there anything that pauses one class without using multithreading?
You don't pause classes, you pause threads. In the moment you pause your only thread, you pause you entire application as well. So there is no way to pause your only thread and expect the application will continue to run. You would need more than one thread if you expect your application do more than just waiting.
I think you're confusing some concepts here. Classes and Objects do not run. Threads run, and what they run are the instructions (code) defined by classes and objects.
So no, you cannot pause a Class or Object, only a Thread. Moreover, if your application is single threaded, then you only have a "main" thread, and if you pause that thread then your whole application will pause.
You can't pause a "class" per se. A class is just a "dead" container.
What you can do is pause a thread or a task.
Typically, you would create a separate thread to run the task you want to pause, and pause it when you like - because it runs in a separate thread, it will not hang you whole program.
See this simple example which you can run to better understand how threads can run in parallel:
public static void main(String[] args) throws InterruptedException {
Runnable lazyTask = new Runnable() {
#Override
public void run() {
System.out.println("Lazy: I feel like sleeping for a second");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
System.out.println("Lazy: I feel better now");
}
};
new Thread(lazyTask).start();
//Let's wait a bit until the lazy task goes to sleep
Thread.sleep(100);
//now you can do something that will not hang
System.out.println("Main: I'm sleeping too, but only half a second");
Thread.sleep(500);
System.out.println("Main: And I can continue my job while that lazy task is still asleep");
}
No. You cannot. You have the main thread . Sleep will pause it. If you want stop run something without affect the main thread you need to fork it from the main thread , by use addiotnal thread

How does one stop a thread without a stop() method?

I have question about the Java threads. Here is my scenario:
I have a thread calling a method that could take while. The thread keeps itself on that method until I get the result. If I send another request to that method in the same way, now there are two threads running (provided the first did not return the result yet). But I want to give the priority to the last thread and don't want to get the results from the previously started threads. So how could I get rid of earlier threads when I do not have a stop method?
The standard design pattern is to use a local variable in the thread that can be set to stop it:
public class MyThread extends Thread {
private volatile boolean running = true;
public void stop() {
running = false;
}
public void run() {
while (running) {
// do your things
}
}
}
This way you can greacefully terminate the thread, i.e. without throwing an InterruptedException.
The best way really depends on what that method does. If it waits on something, chances are an interrupt will result in an InterruptedException which you handle and cleanly exit. If it's doing something busy, it won't:
class Scratchpad {
public static void main(String[] a) {
Thread t = new Thread(new Runnable() {
public void run() {doWork();}
});
t.start();
try {
Thread.sleep(50);
} catch (InterruptedException ie) {}
t.interrupt();
}
private static void doWork() {
for ( long i = 1; i != 0; i *=5 );
}
}
In the case above, the only viable solution really is a flag variable to break out of the loop early on a cancel, ala #inflagranti.
Another option for event-driven architectures is the poison-pill: if your method is waiting on a blocking queue for a new item, then you can have a global constant item called the "poison-pill" that when consumed (dequeued) you kill the thread:
try {
while(true) {
SomeType next = queue.take();
if ( next == POISON_PILL ) {
return;
}
consume(next);
}
} catch //...
EDIT:
It looks like what you really want is an executor service. When you submit a job to an executor service, you get back a Future which you can use to track results and cancel the job.
You can interrupt a Thread, its execution chain will throw an InterruptedException most of the time (see special cases in the documentation).
If you just want to slow down the other thread and not have it exit, you can take some other approach...
For one thing, just like exiting you can have a de-prioritize variable that, when set, puts your thread to sleep for 100ms on each iteration. This would effectively stop it while your other thread searched, then when you re-prioritize it it would go back to full speed.
However, this is a little sloppy. Since you only ever want one thing running but you want to have it remember to process others when the priority one is done, you may want to place your processing into a class with a .process() method that is called repeatedly. When you wish to suspend processing of that request you simply stop calling .process on that object for a while.
In this way you can implement a stack of such objects and your thread would just execute stack.peek().process(); every iteration, so pushing a new, more important task onto the stack would automatically stop any previous task from operating.
This leads to much more flexible scheduling--for instance you could have process() return false if there is nothing for it to do at which point your scheduler might go to the next item on the stack and try its' process() method, giving you some serious multi-tasking ability in a single thread without overtaxing your resources (network, I'm guessing)
There is a setPriority(int) method for Thread. You can set the first thread its priority like this:
Thread t = new Thread(yourRunnable);
t.start();
t.setPriority(Thread.MIN_PRIORITY); // The range goes from 1 to 10, I think
But this won't kill your thread. If you have only two threads using your runnable, then this is a good solution. But if you create threads in a loop and you always sets the priority of the last thread to minimum, you will get a lot of threads.
If this is what is application is going to do, take a look at a ThreadPool. This isn't an existing class in the Java API. You will have create one by yourself.
A ThreadPool is another Thread that manages all your other Threads the way you want. You can set a maximum number of running Threads. And in that ThreadPool, you can implement a system that manages the Thread priority automatically. Eg: You can make that older threads gain more priority, so you can properly end them.
So, if you know how to work with a ThreadPool, it can be very interesting.
According to java.lang.Thread API, you should use interrupt() method and check for isInterrupted() flag while you're doing some time-consuming cancelable operation. This approach allows to deal with different kind of "waiting situations":
1. wait(), join() and sleep() methods will throw InterruptedExcetion after you invoke interrupt() method
2. If thread blocked by java.nio.channels.Selector it will finish selector operation
3. If you're waiting for I/O thread will receive ClosedByInterruptException, but in this case your I/O facility must implement InterruptibleChannel interface.
If it's not possible to interrupt this action in a generic way, you could simply abandon previous thread and get results from a new one. You could do it by means of java.util.concurrent.Future and java.util.concurrent.ExecutorService.
Cosider following code snippet:
public class RequestService<Result> {
private ExecutorService executor = Executors.newFixedThreadPool(3);
private Future<Result> result;
public Future<Result> doRequest(){
if(result !=null){
result.cancel(true);
}
result = executor.submit(new Callable<Result>() {
public Result call() throws Exception {
// do your long-running service call here
}
});
return result;
}
}
Future object here represents a results of service call. If you invoke doRequest method one more time, it attempts to cancel previous task and then try to submit new request. As far as thread pool contain more than one thread, you won't have to wait until previous request is cancelled. New request is submitted immediately and method returns you a new result of request.

How do you hang a thread in Java in one line?

By one line I mean at most 100 chars per line.
(I basically need this to keep the program alive. The main thread registers callback listeners that are run in separate threads. I just need the main one to hang forever and let the other threads do their work)
synchronized(this) {
while (true) {
this.wait();
}
}
(thanks to Carlos Heuberger. Exception handling omitted in the above code)
This will make the current thread wait on the monitor of the current class until someone calls notify(), or forever.
There are a few things you could do that would be better than hanging the initial thread forever:
Use otherThread.join(). This will cause the current thread you are running in to sleep until the other thread has finished executing.
As #nanda suggests, use ExcecutorService.shutdown() to wait until a pool of threads has finished.
Use otherThread.setDaemon(false) and simply let your initial thread exit. This will set your new threads as user threads. Java will not shut down until the only threads running are daemon threads.
Thread.sleep(Long.MAX_VALUE);
Ok, so it isn't forever, but talk about a really long time :)
Use executor. By using method shutdown() you'll force the executor to wait until all threads are finished.
With a CountDownLatch you can wait untill the count down reached 0, if you make sure it never counts down, maybe only when it needs to end. (This also result in 0% cpu, the opposite of loops that will run forever, and with join() your app will still finish when all other threads finished, The option of the executor is better, but will also end when all executed task have finished)
You can use thread.join to wait for all of the threads.
Here is a solution that is a one-liner, in that you only have to add one extra line. (You do have to add synchronized and throws InterruptedException to your main declaration though.) Also, it does not need access to, or even knowledge of the threads in the library you are using.
public static synchronized void main(String[] args) throws InterruptedException{
...
YourMainClass.class.wait(); // wait forever
}
It assumes you will never call notify on your main class and that you want to exit if you get an InterruptedException. (You can add a while (true) { ... } around the wait line if you really want to guard against that.)
public static void main(String[] args) {
Thread t = new Thread() {
#Override
public void run() {
try {
while (true) {
Thread.sleep(1000);
}
} catch (InterruptedException e) {
}
}
};
t.setDaemon(false);
t.start();
}
while(true) { Thread.sleep(1000); }
for(;;);
But it's very unlikely that hanging the thread is what you want. Instead, you should consider options like joining on the other threads.

Java: Stopping a thread that has run for too long?

Say I've got something like this
public void run(){
Thread behaviourThread = new Thread(abstractBehaviours[i]);
behaviourThread.start();
}
And I want to wait until abstractBehaviours[i] run method has either finished or run for 5000 milliseconds. How do I do that? behaviourThread.join(5000) doesn't seem to do that afaik (something is wrong with my code and I've put it down to that).
All the abstract abstractBehaviour class is of course Runnable. I don't want to implement it inside each run method as that seems ugly and there are many different behaviours, I'd much rather have it in the calling/executing thread and do it just once.
Solutions? First time doing something as threaded as this. Thanks!
edit: So the interrupting solution would be ideal (requiring minimal changes to AbstractBehaviour implementations). BUT I need the thread to stop if it has finished OR 5000 milliseconds have passed so something like the following would not work because the thread may finish before the while loop in the parent thread has. Make sense? Any ways around this, I'd love to do it from within the thread that starts the threads obviously.
long startTime = System.currentTimeMillis();
behaviourThread.start();
while(!System.currentTimeMilis - startTime < 5000);
behaviourThread.interrupt();
try {
behaviourThread.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
edit: nevermind I see there is a Thread.isAlive() method, all solved I think
The best way to do this is to use the thread interrupt mechanism. The worker thread / Runnable needs to periodically call Thread.interrupted() to see if it is time to stop. The second part of the equation is that a separate thread needs to call Thread.interrupt() on the worker thread after 5000 milliseconds have elapsed.
The advantages of using thread interrupts (over a bespoke solution using flags) include:
The interrupted() state is always available for the current thread. You don't need to pass around an object handle or use a singleton.
An interrupt will unblock some blocking IO and synchronization requests. A bespoke solution cannot do this.
Third-party Java applications and libraries may respect Thread.interrupt().
EDIT - as a commenter points out, you can test whether the current thread has been interrupted using either Thread.interrupted() or Thread.currentThread().isInterrupted(). The main difference between the two approaches is that the former clears the interrupted flag, but the latter doesn't.
You cannot do this externally from the run method - the run method must check some variable to see if it should exit. For example:
class InterruptableRunnable implements Runnable
{
private volatile boolean stop;
public setStop() {
stop = true;
}
public void run() {
while (!stop)
{
//do some work and occassionaly fall through to check that stop is still true
}
}
}
The key thing is for the code in the run loop to check the stop flag occasionally. You can then wire up a timer to set stop to true after 5000 milliseconds.
Finally, it's best practice not to use Threads directly, use the excellent Concurrency Framework. The Concurrency Tutorial is a good place to start and the book Java Concurrency in practice is excellent.
You may do it using java.util.concurrent package.
ExecutorService service = Executors.newCachedThreadPool();
Future future = service.submit(behaviourThread);
long startTime = System.currentTimeMillis();
while (!future.isDone()) {
if (System.currentTimeMillis() - startTime > 5000) {
future.cancel(true);
break;
}
}
// TODO: more work here
//don't forget to shutDown your ThreadPool
service.shutDown();
This code will stop your thread after 5 seconds if it has not finished it's job by that time. If you check behaviourThread.isAlive() it's gonna show false.
You do that by implementing a Runnable
public void run()
{
long time = System.nanoTime(),
end = time + 5 000 000 000; // just better formatting
do {
...my code
} while (System.nanoTime() < end && myOwnCondition);
}
Interrupt is not such a good solution, because you need to access the thread from outside
and it disturbs the program flow. The thread can terminate anytime in your code which
makes cleanup difficult. Please form a habit of letting threads run to the end because otherwise it opens nasty and difficult bugs.
If your program is so heavy duty that you don't know that the while end is reached until the task has completed I suggest the use of a labeled break:
do {
breakout:
{
..my code
if (timetest)
break breakout;
}
// cleanup
...
} while (...);

Categories