Seems to be that this method is takes in an array of threads, then determines if they have completed using InterruptedException, which seems plausible to me.
private static void waitUntilAllThreadsFinished(Thread[] threadArr) {
for(int i=0; i<threadArr.length; i++) {
try {
threadArr[i].join();
} catch (InterruptedException e) { }
log.debug("thread ["+threadArr[i].getName()+"] have completed");
}
}
If you just want to know if the thread has been interrupted , the use public boolean isInterrupted() method on the thread reference. This code is trying to block the current thread on each of the thread's completion, and retrying if it got interrupted in th meanwhile.
I think getState is more appropriate
I would not force the throw and catch, since it is not free of cost. The Thread class have methods to access the current state of an instance.
This code does not just determine whether all threads have completed, but waits for all of them to complete. And it's not using InterruptedException to do this. If join() calls on finished (dead) thread, the code just continues on without exception.
But it will work, I guess...
Related
I have made a method to send an e-mail, and I wanted to try if it was possible to call a method inside the method itself with a timer, to do like a scheduler
public void createExcel(){
int year = Calendar.getInstance().get(Calendar.YEAR);
int num_week = data.getCurrentWeek()-1;
ArrayList<DHDemande> ListeDemandes = d.getDemandesForPaie(num_week, year);
try {
data.createFile(ListeDemandes);
Thread.sleep(20000);
createExcel();
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
But now the method doesn't stop (it was obvious) but even if I refresh Apache and if I change the method. How can I stop it ? because I receive an email every 20 second now
The thing with Treads is that there is now save way to tell it to just stop without memory leaks. You can use thread.stop(), this will kill the thread but it may cause memory problems if your objects are too big.
Quote from java doc:
stop() Deprecated. This method is inherently unsafe. Stopping a
thread with Thread.stop causes it to unlock all of the monitors that
it has locked (as a natural consequence of the unchecked ThreadDeath
exception propagating up the stack). If any of the objects previously
protected by these monitors were in an inconsistent state, the damaged
objects become visible to other threads, potentially resulting in
arbitrary behavior. Many uses of stop should be replaced by code that
simply modifies some variable to indicate that the target thread
should stop running. The target thread should check this variable
regularly, and return from its run method in an orderly fashion if the
variable indicates that it is to stop running. If the target thread
waits for long periods (on a condition variable, for example), the
interrupt method should be used to interrupt the wait. For more
information, see Why are Thread.stop, Thread.suspend and Thread.resume
Deprecated?.
Explore the Thread api and see if you can find anything else that suites your needs.
As Borislav mentioned, stop() is incorrect here, you need to call and handle interrupt().
class Test
{
public static Thread helloWorldLater()
{
Thread t = new Thread(new Runnable(){
#Override public void run()
{
try {
Thread.sleep(200);
System.out.println("Hello World");
}
catch(InterruptedException ex)
{
// clean up here
return;
}
}
});
t.start();
return t;
}
public static void main(String[] args) throws InterruptedException
{
Thread t = helloWorldLater();
Thread.sleep(100);
t.interrupt();
// no "Hello World" to be seen
}
}
Alternatively, depending on your Java version, you can also use the more modern concurrency Java APIs.
Besides Borislavs and Konrads legitimate comments on thread.stop(), you are calling the createExcel() method recursively (after Thread.sleep(20000)), so obviously your method will run forever. If you remove that call it should work like you expect it.
I've used Thread.sleep for all kinds of different reasons, but one thing I've never understood is when an exception would occur during this try /catch block:
try {
Thread.sleep(1000); // sleep for 1 second.
} catch (Exception x) {
fail("Failed due to an exception during Thread.sleep!");
x.printStackTrace();
}
What would have to occur within the computer to actually hit an exception on Thread.sleep? My best guess, would be that maybe the system clock has a once in a lifetime "skip of a beat" like a heartbeat, but how often does this happen..
So in essence, my question is: When executing Thread.sleep, what would have to occur internally for #sleep to throw an exception?
If you look in the JavaDoc for Thread.sleep() you see exactly what might happen:
Throws:
IllegalArgumentException - if the value of millis is negative
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
An example on how to interrupt another thread might look like this:
public class Foo {
public static void main(final String[] args) throws Exception {
Thread sleepThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Interrupted!");
}
}
});
sleepThread.start();
Thread.sleep(500);
sleepThread.interrupt();
}
}
This will print
Interrupted!
The Thread class defines an interrupt method. When it's called (obviously from another thread) by a thread and there's no security exception, an InterruptedException is thrown.
The purpose is, precisely (and normally), to interrupt the sleep.
Thread.sleep(someValue) can fire InterruptedException.
More info about handling this exception and reson for this you can find here.
You can find a lot usefull answers on SO. Here is the one for example:
When does Java's Thread.sleep throw InterruptedException?
When a thread interrupt is issued, for example if a signal was sent to shut the JVM down.
The Thread can throw an InterruptedException (which you should use instead of general Exception) when the Thread is interrupted (usually by the interrupt() method called from another Thread) instead of just waiting. It has nothing to do with the sleep() method.
I am trying to construct two threads, thread A is the main thread and thread B is the second thread, thread B is updating a variable through a time consuming function (this variable should be shared between both threads, because eventually thread A needs to use that variable as well), but I want thread A to terminate thread B if thread B takes too long to complete (using an exception).
What I tried is the following:
Thread thread = new Thread() {
public void run() {
/// run something that could take a long time
}
};
synchronized (thread) {
thread.start();
}
System.err.println("Waiting for thread and terminating it if it did not stop.");
try {
thread.wait(10000);
} catch (InterruptedException e) {
System.err.println("interrupted.");
}
Should that give the expected behavior of terminating a behavior in case it has run more than 10 seconds? The thread object gets deleted after the wait, because the method that runs the thread returns.
Right now, what happens with this code is that I always get java.lang.IllegalMonitorStateException on the wait(10000) command.
You will always get a IllegalMonitorStateException if you are calling wait() on an object that you are not synchronized on.
try {
// you need this to do the wait
synchronized (thread) {
thread.wait(10000);
}
} catch (InterruptedException e) {
System.err.println("interrupted.");
}
If you are waiting for the thread to finish then you probably are trying to do a:
try {
thread.join(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("interrupted.");
}
Unfortunately, you do not know at that point if the thread is running because join doesn't return whether or not it timed out (grumble). So you need to test if the thread.isAlive() after the join.
If you are asking how you can cancel the thread if it runs for longer than 10000 millis, then the right thing to do is use thread.interrupt(). This will cause any sleep() or wait() methods to throw an InterruptedException and it will set the interrupt flag on the thread.
To use the interrupt flag your thread should be doing something like:
while (!Thread.currentThread.isInterrupted()) {
// do it's thread stuff
}
Also, it is always a good pattern to do something like the following because once the InterruptedException is thrown, the interrupt flag has been cleared:
} catch (InterruptedException e) {
// set the interrupt flag again because InterruptedException clears it
Thread.currentThread.interrupt();
System.err.println("interrupted.");
}
That code is incorrect. Method wait is declared in Object class and is intended to suspend current thread using as monitor instance of the object on which it is called. You may invoke this method only in synchronized section, that is why you get your exception.
Regarding to your problem: in general you can not stop another thread if it does not want to stop. So you should invoke Thread.interrupt to notify the thread that it should stop working and it is up to that thread to decide to take into account that notification or not. To check if thread is interrupted you may use interrupted() or isInterrupted() methods.
Why invoke the method Thread.currentThread.interrupt() in the catch block?
This is done to keep state.
When you catch the InterruptedException and swallow it, you essentially prevent any higher-level methods/thread groups from noticing the interrupt. Which may cause problems.
By calling Thread.currentThread().interrupt(), you set the interrupt flag of the thread, so higher-level interrupt handlers will notice it and can handle it appropriately.
Java Concurrency in Practice discusses this in more detail in Chapter 7.1.3: Responding to Interruption. Its rule is:
Only code that implements a thread's interruption policy may swallow an interruption request. General-purpose task and library code should never swallow interruption requests.
I think this code sample makes things a bit clear.
The class which does the job :
public class InterruptedSleepingRunner implements Runnable {
#Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
// You are kidding me
System.out.println(i + " " + i * 2);
// Let me sleep <evil grin>
if (Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
} else {
sleepBabySleep();
}
}
}
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
The Main class:
public class InterruptedSleepingThreadMain {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new InterruptedSleepingRunner());
thread.start();
// Giving 10 seconds to finish the job.
Thread.sleep(10000);
// Let me interrupt
thread.interrupt();
}
}
Try calling interrupt without setting the status back.
Note:
http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
How do I stop a thread that waits for long periods (e.g., for input)?
For this technique to work, it's critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the InterruptedException is not declared to throw this (checked) exception, then it should "reinterrupt itself" with the following incantation:
Thread.currentThread().interrupt();
This ensures that the Thread will reraise the InterruptedException as soon as it is able.
I would consider it a bad practice or at least a bit risky.
Usually higher level methods do not perform blocking operations and they will never see InterruptedException there. If you mask it in every place you perform interruptible operation, you will never get it.
The only rationale for Thread.currentThread.interrupt() and not raising any other exception or signaling interrupt request in any other way (e.g. setting interrupted local variable variable in a thread's main loop) is the situation where you really can't do anything with the exception, like in the finally blocks.
See Péter Török's answer, if you want to better understand implications of the Thread.currentThread.interrupt() call.
Refer from java doc
If this thread is blocked in an invocation of the wait(), join(),
sleep(long), then its interrupt status will be cleared and it will
receive an InterruptedException.
If this thread is blocked in an I/O operation, the thread's interrupt
status will be set, and the thread will receive a
ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt
status will be set and it will return immediately from the selection
operation.
If none of the previous conditions hold then this thread's interrupt
status will be set.
So, if you change the sleepBabySleep() method in #Ajay George Answer to I/O operation or just a sysout, you don't have to set the status back to stop the program. (BTW, they don't even throw InterruptedException)
Just like #Péter Török said => This is done to keep state. (And particular for method that will throw InterruptedException)
I am trying to have my main thread spawn off a new thread and, after some time, raise the interrupt flag. When it does so, the spawned thread should see that flag and terminate itself.
The main thread looks something like this:
final Thread t = new Thread()
{
#Override
public void run()
{
f();
}
};
t.start();
try
{
t.join(time);
t.interrupt();
if(t.isAlive())
{
t.join(allowance);
if(t.isAlive())
throw new Exception();
}
}
catch(Exception e)
{
System.err.println("f did not terminate in the alloted time");
}
And the spawned thread has a bunch of the following scattered throughout its code:
if(Thread.interrupted()) return;
When I am in debug mode, everything works perfectly. The interrupt flag is raised by the main thread and is caught by the spawned thread. However, in regular run mode the spawned thread doesn't seem to receive the interrupt flag, no matter how long I set the allowance.
Does anyone know what I am doing wrong?
Note: I am using Ubuntu and I am all-together new to anything Linux. Can the problem be with the OS? I have not tested the code on any other OS.
Here are my guesses:
When main thread calls t.interrupt(); the t thread has already finished execution.
When main thread calls t.interrupt(); in the t thread there are no more calls to check interrupted() flag.
You get the exception as a result of running the code? Do you get the exception you throw in your code after "allowance" time or you got some other like ThreadInterruptedException or similar? Try writing the message of the caught exception...
I suggest you consider using an ExecutorService which is designed to do this sort of thing and could help you in other ways.
ExecutorService service = Executors.newCachedThreadPool();
Future<ResultType> future = service.submit(new Callable<ResultType() {
public ResultType call() throws Exception {
// do soemthing
return (ResultType) ...;
}
);
// do anything you like until you need to result.
try {
ResultType result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException timedOut) {
// handle exception
// cancel the task, interrupting if still running.
result.cancel(true);
} catch (ExecutionException taskThrewAnException) {
// handle exception
}
// when you have finished with the service, which is reusable.
service.shutdown();
Do you have nested checks of Thread.interrupted()? That method clears the interrupted flag, so the second call returns false. You could use isInterrupted() instead.
It looks as though the Thread.interrupted() call is not being reached in f().
The different behaviour you are seeing in Debug and Run modes is likely to be due to a race condition.