Thread doesn't seem to exit cleanly - thread hang - java

So I was trying to do some testing based off some things I know about the Java Memory Model (JMM) because I wanted to see how they applied to a initialization+assignment in a try-catch block with an exception thrown, and I obtained the results I wanted (not related, but I wanted to know if in a try-catch if the allocation could happen before the initialization, and in turn before some exception was thrown, could some other Thread see the uninitialized Object before the Exception was thrown - the answer seems to be no), however I encountered something odd related to my Thread running.
Basically, my Thread never seems to exit. I ran my code to completion in a debugger, and I can see the two Threads running. My main Thread being Thread, and the Thread I created Thread-1. After I complete the main method, my main Thread goes away and is replaced with DestroyJavaVM, as expected. However, Thread-1 seems to be waiting on something.
The part that really confuses me, other than the code being too simple to screw up, is that if I put a
System.out.print("");
inside of the while block, then the slow down caused by I/O seems to cause the Thread to "catch-up" on whatever it was doing, and see the interrupt. Another thing I noticed, is that if I put a breakpoint on the "finished" #println() statement, that the Thread will break on that line, and allow me to continue which causes the print statement in the standard-out, and the program exits. That doesn't make a lot of sense to me. What is happening behind the scenes that causes the created Thread not see the interrupt?
Here is the code I have for my testing, with the unimportant bits removed that were related to me testing the JMM:
public class Foo{
static Foo p;
public static void main(String [] args){
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
}
System.out.println("finished");
}
});
t.start();
for(int i = 0; i < 100000; i++){
try{
p = new Foo();
}catch(Exception pse){
}
}
t.interrupt();
System.out.println("main-method-completed");
}
}

You have probably reproduced the bug JDK-6772683 : Thread.isInterrupted() fails to return true on multiprocessor PC.

As long as the thread runs its while-loop it won't get any messages from other threads in the system. If you do, for instance, Thread.sleep(1); the thread is paused, and a context switch to something else occurs. When the thread is restored, it will get the interrupt notification from some the main loop thread.
If you want to stop the loop in the thread you could either use a volatile variable (these are written and read explcitly from shared memory and are quite expensive), or use, for instance, an java.util.conncurrent.atomic.AtomicBoolean, which at least in theory could use some less expensive method for communicate the its state between threads.

Related

How to end a thread after coming out of a for loop

So I have a program that prints Hello and Goodbye by using 2 threads.
I need to print Hello 100 times and Goodbye 100 times.
This is working fine, however, after it prints, the program hangs and doesn't finish.
I have a feeling it is because the threads aren't finishing up.
I was wondering what the best way to do this is?
So my main is like this
public static void main(String [] args)
{
Object lock = new Object();
new HelloThread(lock).start();
new GoodbyeThread(lock).start();
}
And here is the HelloThread class. GoodbyeThread looks the same:
class HelloThread extends Thread
{
private Object lock;
private boolean isRunning = false;
HelloThread(Object l)
{
this.lock = l;
}
public void run()
{
for(int i = 0; i < 100; i++)
{
synchronized(lock)
{
isRunning = true;
System.out.println("Hello");
lock.notify();
try
{
lock.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
I was thinking there might be a way to have the isRunning variable be used to close the thread, however I'm not sure what the best way to go about it.
Thanks for any help
The for loop isn't important, the key things happen in the last iteration. It is very probable that one of the threads will enter its wait() after the other thread has already executed its notify(), thus missing the only chance to break out of that wait().
Your GoodbyeThread is waiting for your HelloThread to send a notify().
What is likely happening at i == 99:
HelloThread prints "Hello" calls notify(), then calls wait()
GoodbyeThread prints "Goodbye" calls notify() [here HelloThread exits the for loop and terminates], then calls wait().
Nothing will ever call notify() to end the wait() of the GoodbyeThread.
One fix would be to only call wait() if i < 99.
This is working fine, however, after it prints, the program hangs and doesn't finish. I have a feeling it is because the threads aren't finishing up.
If the thread is leaving the run() method then it will finish up. I suspect that your thread is stuck on lock.wait() after the 100th printing of "Hello". If you use jconsole or dump a thread stack trace you should be able to see where the threads are stuck.
One thing to realize is that if you call lock.notify() the only time the other thread will get the notification is if it is in lock.wait(). Notify calls do not queue up.
As mentioned above: the thread is deadlocking because at least one of them is still waiting for the notify() call.
Imagine you only had one run to do (print "Hello world" only once):
Thread A starts, prints "Hello", then runs notify(), but no one is listening, then wait().
Thread B starts, prints "World", then runs notify().
Thread A wakes up and tries to regain the monitor lock but this one is still hold by Thread B, so Thread A has to wait further.
Thread B runs wait(), releasing the monitor.
Thread A wakes up again, regains the monitor and finishes the loop.
Thread B still waits, but is never woken up.
This can be solved through an exit notify like this:
for(int i = 0; i < 100; i++) {
// ...
}
synchronized (lock) {
lock.notifyAll();
}
The wait/notify constructs are the most basic tools for threading, and not well suited for many threading problems out there, as they very often can result in deadlocks or worse. For easier and less error-prone threading concepts, you should use the concurrent package, which has ready-made tools available for most problems out there.
But it is necessary to be familiar with these tools, and you absolutely must design your code around these tools and not vice versa. An existing program cannot be just filled up with multi-threading to make it faster, it needs to be designed for it before you even write the first line of code. Otherwise you run into many issues, including that your result might be slower than a single-threaded execution would have been.

Only one thread have access to a certain part of code?

I have a project which requires logging in my router from time to time and make some changes. In eclipse I have a separate project which deals with all the things I need changed and I have that in the build path of my main project which is a multi threaded project. My problem is that sometimes two threads try to access the router which messes things up. Is there anything I can do that only one thread can access a certan part of my code.
This is the related code for the main multithreaded application
if (totalLogins > 10)
{
IpManager.rebootRouter();
Thread.sleep(4000);
totalLogins = 0;
composedMessagesWithThisIP = 0;
}
And in the other project this is what I have
public synchronized static void rebootRouter()
{
try
{
//code related to restart modem
}
catch (Exception e)
{
}
}
So what I have done is made the method synchronized but I believe from time to time more than one thread access the "rebootRouter" method. Which causes problems in my main application.
What is the best way and most effective way to make IpManager.rebootRouter() be executed by one thread only?
Regards!
synchronized guarantees that only one thread can enter the block at a time, but AFAIR the same thread can enter the block multiple times (so threads don't deadlock against themselves), and if a thread is blocked because another thread is in there then it may run immediately after the first thread leaves the synchronized block.
First I'd throw logging at the entry and exit points of the routine.
I'd check to see that you don't have any recursion going on, and make sure that the calls really are running at the same time. Also, remember if there's any asynchronous work or callbacks the synchronized block may be exited.
Use Semaphore from java.util.concurrent package, to restrict the Number of thread accessing the object.
Example:
Here in this code snippet, only 1 thread can access the object at a time.
Semaphore s = new Semaphore(1);
s.acquire();
synchronized(this){
// Your modem work
}
s.release();
So what I have done is made the method synchronized but I believe from time to time more than one thread access the "rebootRouter" method.
As you have marked this method as synchronized it guarantees that more than one thread can not execute this method simultaneously . It may be code in side // Your modem work has some unsynchronized stuff that may cause problem.
My problem is that sometimes two threads try to access the router which messes things up. Is there anything I can do that only one thread can access a certan part of my code.
Define "messes things up". Since rebootRouter is synchronized, only one thread can run that method at any given time. But if a thread, call it thread A, tries to invoke it while another thread (thread B) runs it, thread A will block until B returns from rebootRouter, and A will then directly call rebootRouter itself. If this is the behavior you want, your problems are elsewhere (synchronized is not broken, or someone would've noticed).
If you want thread A in the example above to not invoke rebootRouter if it is called by another thread when in the example above, you can use Lock.tryLock:
private static final Lock lock = new ReentrantLock();
public static void rebootRouter() {
if (!lock.tryLock()) return;
try {
//code related to restart modem
} catch (Exception e) {
// Note: Empty catch blocks considered bad style
} finally {
lock.unlock();
}
}
If your needs are more specific, you probably need to rephrase your question.

Question on Java Thread, output consistent

In the below code the answer is always Started 0 1 2 3 Complete. Im just wondering how it is possible.
If someone could help with the consistency of the output, it would be nice
public class TestOne extends Thread {
/**
* #param args
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
Thread t = new Thread(new TestOne());
t.start();
System.out.println("started");
t.join();
System.out.println("Complete");
}
public void run(){
for(int i=0;i<4;i++){
System.out.println(i);
}
}
Most likely you're getting the same results because, most of the time, the main thread starts a new thread then, before that new thread has a chance to print anything, the main thread prints its started message. The join in the main thread then forces it to wait until the other thread has finished, then it prints Complete.
You have a race condition here. The instant you start the second thread, it's indeterministic as to which order the lines will be output (other than the complete line which is made deterministic by virtue of the wait call, as previously mentioned).
But a race condition doesn't guarantee that you'll get different results on multiple runs, only that it is possible. You still shouldn't rely on that behaviour, of course.
For example, the following code:
public class TestOne extends Thread {
public static void main (String[] args) throws Exception {
Thread t = new Thread (new TestOne());
t.start();
Thread.sleep (1000); // <- Added this.
System.out.println ("Started");
t.join();
System.out.println ("Complete");
}
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println (i);
}
}
}
will output:
0
1
2
3
Started
Complete
Although, even then, the order is not guaranteed as it may take more than a second for the thread to "warm up" - sleep is rarely a good solution to race conditions. I've just used it here for illustrative purposes.
When you say Thread t = new Thread(); nothing special happens because you are not creating a "Thread" per se. It is just an object that has the "characteristics" to become a thread of execution. For the object to be a "Thread" you have to call t.start(); and this is where the magic lies.
When you say t.start() the JVM creates a new stack for the newly created thread to run. It associates that stack to the thread object in question. And then makes it available for scheduling. Basically this means that it queues the thread in the JVM scheduler and in the next time slice it is also available for execution. The JVM actually does a lot more than this, my answer is just oversimplified for your example.
Invariably, meanwhile all these thread + stack creation, your main thread has the opportunity to move to its next instruction which in your case is System.out.println("started");.
Theoretically, what you say is true, "Started" could come anywhere in between 0, 1, 2, 3. However in reality, since your t.start() is an "expensive" method, it takes some time to complete, during which the main thread generally gets the chance to execute its next instruction.
If you want to know the details of t.start(); look into the Java source code.
Clearly, you are seeing a consistent result (and this particular result) because on your machine the call to the child thread's run method is consistently happening after the println in the main thread.
Why is it consistent?
Well, simply because your platform's native thread library is behaving in a consistent fashion!
Typical modern Java virtual machine implementations use the host operating system's native thread support to implement Java threads, and to perform Java thread scheduling. On your machine, the native thread implementation appears to be consistently allowing the current thread to return from the Thread.start() call immediately and keep executing.
However, it is not guaranteed that this will always happen. For instance, if the machine was heavily loaded and the main thread had just about exhausted its current timeslice, it could get descheduled during or immediately after the start call, allowing the new thread to run first.
Furthermore, on another platform the normal scheduler behaviour could be different. The scheduler could consistently cause the current thread to deschedule and let the new one go first. Or it could happen "randomly".
The JVM and Java library specs deliberately do not specify which thread "goes first" precisely to allow for differences in the thread implementation ... and variation due to differences in hardware, system load and so on.
Bottom line - the apparent consistency you are seeing is an "artifact", and you shouldn't rely on it, especially if you want your application to work on a wide range of JVMs.
Simply put, the scheduling of the started thread with respect to the main thread is JVM implementation dependent. But that being said, most implementations, if not all, will leave the starting thread running to the completion of its timeslice, until it blocks on something, or until it is preempted by a higher priority thread (if preemptive scheduling is being used, also JVM implementation dependent).
The Java spec just does not say very much which is very specific about threading, deliberately to grant JVM writers the most scope for their implementation.
t.join() means "block until thread t has finished", which explains the "Completed" being last.
EDIT: In answer to question re "Started"...
The call to Thread.start() means "please schedule this thread to run", and it will start when java feels like starting it. The chance of that happening between t.start() the println() is platform dependant, but small on systems I've used (thx to # Stephen C for platform info).
This code however outputs 0, Started, 1, 2, 3, Completed:
Thread t = new Thread(new TestOne());
t.start();
try
{
Thread.sleep(100); // Added sleep between t.start() and println()
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Started");
t.join();
System.out.println("Complete");
When you start a thread it takes time (nothing comes for free or occurs instantly)
The thread which is already running will almost always be quicker to print out than a thread which has just started.
If you really want to the order to be different every time you can use run() instead of start() This works because you only have one thread.

isAlive() method of java thread is not working properly?

I was trying a example of isAlive() method of java threading. But i found that isAlive() method is returning false even if thread has been already started. Can someone please tell me what am i doing wrong? Here is the code snippet.
package app;
public class ThreadAliveDemo {
public static void main(String[] args) {
Thread myThread;
myThread = new Thread()
{
public void run()
{
Thread.sleep(3000);
System.out.println("My Thread.");
}
};
myThread.setName("My Thread");
myThread.start();
if(!myThread.isAlive())
{
myThread.setName("My Thread");
myThread.start();
}
}
}
There's a good chance the thread will have started, executed, and finished, between your call to start() and your call to isAlive().
Java offers no guarantees on the sequence in which these things happen. It could execute the spawned thread immediately, or it may choose to defer it until a bit later.
Incidentally, your code is trying to re-start the thread after it has died. This is not permitted:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
So calling start() after checking isAlive() is never going to work.
If my memory serves me well java has quite long periods between thread switching so it is possible that the isAlive fails because the thread is not yet alive. Try to add some waiting time between thread.start() and thread.isAlive()
I haven't done any multithreading in java yet, but it looks to me like your thread probably will have run and exited before the isAlive() check. After all, looks like your thread just prints something out and then dies.
Happened to me recently, fixed it using
if(yourThread.getState() == Thread.State.NEW){
yourThread.start();
}
instead of yourThread.isAlive();
I don't see the point of the code you have posted. Thread.start() starts the thread: you don't need to start it twice. I don't see how your code can realistically into a situation where it has a Thread and doesn't know whether it has been started or not; anyway there are plenty of ways to code around that so it can't happen.

addShutdownHook and setUncaughtExceptionHandler doesn't work as expected in java

I have a multi-threaded program, where I have one thread to watch over several threads. The functioning is designed like this:
Main program does initiation and starts Watcher Thread, in void Main(), I have the line
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownThread(), "Exit Listener"));
When I don't start the watcher thread, the ShutdownThread is called when I terminate the program, but when I start the Watcher thread which has a dead loop in it, the ShutdownThread is not called (I print out a message in that thread). That is very very strange. Any explanations?
The watcher thread is like:
public void run(){
boolean running=false;
thread a=new thread(...); //Do the same thing for b, c, d...
while(true){
if (a.isActive()){
if (running)
thread a= new thread(...);
a.start();
running=true;
}
Thread.sleep(1000); //try catch block...
}
What I would like is a graceful shutdown, that upon getting a terminate signal, shutdownThread is run, sets a flag and interrupts all threads, and waits for the threads to interrupt it, or it timeout so that the remaining threads can be killed. All the threads can catch an interuption, and check if a flag is set, if set, it will interrupt shutdownThread and then exit itself. Instead what I am seeing is all the threads are terminating by itself, doing no cleanup at all.
How about using signals? Is there any good cross-platform code for that?
Then, setUncaughtExceptionHandler doesn't work either. I did testing, and found that the handler isn't called at all. I don't know why. The code for the handler is:
public static class ErrHandler implements Thread.UncaughtExceptionHandler{
public final void uncaughtException(Thread t, Throwable e) {
Error(t + "died, threw exception: " + e);
}
}//this is in public class globals
I hook it using
producer.setUncaughtExceptionHandler(Globals.errhandler);
Is in my code, and I only see the original e.printStack() instead. It seems that I can't override it, either in the parent thread, or in itself. This is so frustrating. I'm thinking of putting a Entry into a queue, and reading it elsewhere. At least that may work.
Oh, the whole purpose is to make sure that if any of the threads die because of runtime exceptions, the watcher thread will check whether the exception is fatal enough, and decide to restart that thread or to quit altogether. At the same time, I would like the program to end gracefully (an interrupt is sent to saver threads so that it dumps the results out, and then interrupts back to tell that we are ready to quit) when the user ends it.
Dunno if it helps you, but we encountered the same behaviour.
Not all exceptions are routed correctly to the registered ExceptionHandler.
I wonder if Unit-Tests exists at all for the concurrent framework. Because this had to be detected.
We implemented the ScheduledExecutorService by ourself by using a ScheduledExecutorService instance as delegate and encapsulate the parameter Runnable/Callable of each method in a Runnable/Callable implementation which corrects the behaviour.

Categories

Resources