Daemon thread with infinite loop not terminating - java

I have a simple test program (garage simulation) with several threads (Vehicle, MysteryVehicle, Observer objects) instantiated and started. Only the Observer object is a daemon thread running an infinite loop.
After all non-daemon threads terminate, Observer thread never does and the loop is executed infinitely (so this isn't some buffered output after the daemon thread really terminates - it does go on forever).
All of the non-daemon threads print something to the console just before exiting their run() methods, and it clearly shows all of them really terminated. I also didn't call join() on the daemon thread. When printing out all currently running threads, observer is listed as well, so my guess is that this daemon thread isn't terminating properly.
The complete code can be found on this commit.
Below you can see all threads created, started and where exactly is join() called.
Main.java
package garage;
import java.util.Set;
import garage.model.*;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
Platform platform = new Platform();
Vehicle.platform = platform;
platform.print();
Vehicle[] vehicles = new Vehicle[30];
for (int i = 0; i < 30; i++) {
vehicles[i] = new Vehicle();
}
for (int i = 0; i < 30; i++) {
vehicles[i].start();
}
Observer observer = new Observer();
observer.platform = platform;
observer.start();
MysteryVehicle mysteryVehicle = new MysteryVehicle();
mysteryVehicle.start();
try {
mysteryVehicle.join();
} catch (Exception exception) {
exception.printStackTrace();
}
try {
for (int i = 0; i < 30; i++)
vehicles[i].join();
} catch (Exception exception) {
exception.printStackTrace();
}
System.out.println("before");
platform.print();
System.out.println("after");
synchronized (Platform.lock) {
System.out.println("END");
System.out.println(platform.flag); // checks whether wait() was called anytime
}
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread t : threads) {
System.out.println(t.getName());
}
}
public static void main(String[] args) {
launch(args);
}
}
Observer.java
package garage.model;
public class Observer extends Thread {
public Platform platform;
static int count = 0;
{
setName("observer");
setPriority(MIN_PRIORITY);
setDaemon(true);
}
#Override
public void run() {
while (true) {
synchronized (Platform.lock) {
try {
System.out.println(++count);
platform.print();
Platform.lock.wait(5000); // hack for when there is no meaningful loop condition
} catch (InterruptedException exception) {
exception.printStackTrace();
} finally {
Platform.lock.notifyAll();
}
}
}
}
}
Vehicle run() method - relevant part
public void run() {
...
System.out.println("done");
}
MysteryVehicle run() method - relevant part
public void run() {
synchronized (Platform.lock) {
System.out.println("And the vehicle disappears!");
...
}
}
All of the relevant thread messages are printed out to the console.
done - 30 times, And the vehicle disappears!, before, after, END, true
This is the list of all of the running threads:
Attach Listener
main
Common-Cleaner
JavaFX Application Thread
Signal Dispatcher
Finalizer
InvokeLaterDispatcher
Reference Handler
QuantumRenderer-0
observer
Thread-2
JavaFX-Launcher
Since the program doesn't terminate and the print() function the run() method of observer calls is executed infinitely, what is it that prevents the daemon thread from terminating?
What am I missing here?

I suspect main() never returns, so the main thread (and perhaps some of those FX threads) are still running.
From the Application doc:
The launch method does not return until the application has exited,
either via a call to Platform.exit or all of the application windows
have been closed.
The posted code has no window to close nor is Platform.exit() invoked.

As far as I know, calling join on daemon thread is a bad idea.The idea behind using daemon thread is it will not halt JVM from exiting. What you can do is send an interrupt to that thread and call join after that.

Related

Running many thread and Stop thread on Exception

I have a Thread (implements Runnable) from many branch officer call that thread with their branch code. I set up a name of their thread with branch code.
The problems are...
When an exception occurred in running thread - I can't stop that. And when try to make another thread with any name "ExceptionInInitializerError" or "OutOfMemoryError: Java heap space" comes
"OutOfMemoryError: Java heap space" exception comes When 2 or more thread running at a time.
public MyRunnerClass {
//This method called from many branch with their branch Code
public void executeBranchProcess(String branchCode){
Thread t = new Thread(new Exporter(branchCode);
t.setName(branchCode);
t.start();
}
}
Thread Class here
public class Exporter implements Runnable{
private String branchCode;
public Exporter(String branchCode){
this.branchCode = branchCode;
}
#Override
public void run() {
try {
exportCorner();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void exportCorner() throws InterruptedException{
try{
//Some Process
}catch(Exception e){
// I want to close running thread here
// I am using closeThread(this.branchCode), but not working
}
}
static void closeThread(String branchCode) throws InterruptedException {
Thread thread = null;
for (Thread t : Thread.getAllStackTraces().keySet()) {
if (t.getName().equals(branchCode))
thread = t;
}
if (thread != null) {
thread.interrupt();
thread.join();
}
}
}
You face multiple problems here:
You cannot join a thread in itself. Thread.join() waits until the thread dies. But if you call it from the thread you want to stop, it just waits forever.
To stop a thread you simply have to return from its run() method. In your case, just add return in your catch clause instead of calling closeThread().
It seems that you have some memory problems. Either whatever you do in exportCorner() uses alot of memory or you create to many threads at once. As Andy Turner has mentioned in the comments, it might be usefull to use an ExecutorService to handle your Runnables. This may help you managing your threads and ensure a limited thread count.

Thread synchronization with Locks and Conditions

I have a problem to understand Locks and Conditions in Java, i do not understand why my code ends up in a deadlock. My programm consists of a Mainthread and a Subthread, subthread is a member of Mainthread. Both threads run in an infinite loop, Subthread's loop is supposed to execute exactly one iteration as soon as it receives the signal for startCond from the Mainthread. Mainthread should wait for the finishCond signal to continue.
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) {
LockTest lt = new LockTest();
Mainthread m1 = lt.new Mainthread();
m1.start();
}
public class Mainthread extends Thread {
private Subthread sub = new Subthread();
public void run(){
System.out.println("Main start");
sub.start();
while(!isInterrupted()) {
try {
sub.getStartLock().lock();
sub.getStartCond().signal();
sub.getStartLock().unlock();
sub.getFinishLock().lock();
sub.getFinishCond().await();
sub.getFinishLock().unlock();
System.out.println("Main done");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Subthread extends Thread {
private Lock startLock = new ReentrantLock();
private Lock finishLock = new ReentrantLock();
private Condition startCond = startLock.newCondition();
private Condition finishCond = finishLock.newCondition();
public Lock getStartLock() {
return startLock;
}
public Lock getFinishLock() {
return finishLock;
}
public Condition getStartCond() {
return startCond;
}
public Condition getFinishCond() {
return finishCond;
}
public void run() {
System.out.println("Sub start");
while(!isInterrupted()) {
try {
startLock.lock();
startCond.await();
startLock.unlock();
finishLock.lock();
finishCond.signal();
finishLock.unlock();
System.out.println("Sub done");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
My expected output would be:
Main done Sub done
(repeated as many times as it was executed in the loops).
Is there a way to solve this problem easier?
The main thread starts, it creates new sub thread and starts it but calling start on a thread does not mean that the thread would receive the processor imeddiatly and that its code will be actually executed.
Main, callss sub.getStartCond().signal(); but at this moment the sub thread is still not running so it misses this signal.
Main, awaits on the finishCond.
Sub starts executing its run method, it goes to the start condition and waits on it for ever.
The deadlock.
Signal wakes up only CURRENTLY waiting thread, it does not 'remember' previous calls.
Use Semaphore instead http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html
it has the semantic of 'counting the permits'.
There might be a more reliable way to do this. I would recommend using a CountDownLatch initialized with a count of 1, instead of a condition. Both the main and child threads can share the same instance of the latch (since the main owns the child that should be easy). The child will call await() and the main will call countDown() when you need to send the signal to the child. I recommend you make the latch private and final.
class ChildThread extends Thread {
private final CountDownLatch signal;
public ChildThread(CountDownLatch signal) {
this.signal = signal;
}
public void run() {
// The loop is necessary in case we get interrupted.
while (true) {
try {
signal.await();
break;
} catch(InterruptedException ignored) {
}
}
// do the work...
}
}
class MainThread extends Thread {
private final ChildThread child;
private final CountDownLatch signalToChild;
public MainThread() {
signalToChild = new CountDownLatch(1);
child = new ChildThread(signalToChild);
}
public void run() {
// I can start the child right away but I'd rather make sure it
// starts if the main thread has started.
child.start();
// prework
// let's signal the child
signalToChild.countDown();
// now the child is working, let's go on with the main thread work
}
}
This works because main and child thread actually share state, i.e., the latch. It does not matter if the main thread decrements the latch before the child thread is actually started, because the child will check this shared state to know if it can start.

How to resume all threads after suspend VM breakpoint in Eclipse?

By default, Eclipse breakpoints are suspending only one thread. This causes application continues to run when I am thinking on breakpoint.
The is another mode for breakpoint - to suspend entire VM. This stops all thread but apparently I am unable to resume an execution or execution behaves differently on resume.
Is it possible to do normal suspend on breakpoints in Eclipse?
UPDATE
There is definitely not my problem, but Eclipse/JVM/other human bug. I made a simple example without any thread interaction:
package tests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Try_EclipseMultithreadedBreakpoint {
private static final Logger log = LoggerFactory.getLogger(Try_EclipseMultithreadedBreakpoint.class);
public static class Thread1 extends Thread {
public Thread1() {
setName("Thread1");
}
#Override
public void run() {
for(int i=0; i<10; ++i) {
log.info("tick {}", i);
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
}
}
}
}
public static class Thread2 extends Thread {
public Thread2() {
setName("Thread2");
}
#Override
public void run() {
for(int i=0; i<15; ++i) {
log.info("tick {}", i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
public static void main(String[] args) {
new Thread1().start();
new Thread2().start();
}
}
then I put an exception into second thread (Thread2):
then I have few breakpoint hits and resumes, then removed breakpoint and resumed, and application hanged.
Below is it's hung state:
as you see by output, thread 1 was not resumed. It printed only one tick and stopped. And it is not waiting for some monitor as reported by Eclipse, it is suspended.
Note, that I didn't set any breakpoints in thread 1, I set them only in thread 2.
Simultaneously, some "Finalizer" thread is waiting for some internal resource.
Also, I noticed, that after breakpoint hit, I was required to press resume several times before it actually resumed.
Select the item as shown on the screenshot and press F8

Why thread not going into waiting status for infinite time?

Below is the code piece which successfully finishes the execution when I run it in my local machine.
I cannot understand why this thread is not going into infinite wait status ?
public class Job extends Thread {
private int counter;
#Override
public void run() {
synchronized (this) {
for (int i = 0; i < 100000; i++) {
counter++;
}
this.notifyAll();
}
}
public static void main(String[] args) throws InterruptedException {
Job job = new Job();
job.start();
synchronized (job) {
job.wait();
}
System.out.println(job.counter);
}
}
Is there any gurantee that above code will always finish execution in every condition ? Can anybody clarify ?
It sure looks like you have a Race Condition on your hands - it all depends on which synchronized(job) happens first - the one in your main thread or the one in the job.
I cannot understand why this thread is not going into infinite wait
status ?
It can, and it will happen if this.notifyAll() is called before job.wait().
Add a flag to test for completion, something like the following:
public class Job extends Thread {
private int counter;
private boolean finished = false;
#Override
public void run() {
synchronized (this) {
for (int i = 0; i < 100000; i++) {
counter++;
}
finished = true;
this.notifyAll();
}
}
public static void main(String[] args) throws InterruptedException {
Job job = new Job();
job.start();
synchronized (job) {
while (!job.finished)
job.wait();
}
System.out.println(job.counter);
}
}
That way you can guarantee that the program will not run into a race condition and will wait forever. Also note that you are now protected against spurious wakeups.
There are a few possibilities
The main Thread enters the synchronized first and wait()s. In this case, the program will terminate because the job Thread will call notify() on the synchronized object.
The job Thread enters the synchronized block first and calls notify() before the main Thread calls wait(), ie. main Thread can't because it waits at the synchronized block. This will block the application as the main Thread will not be able to return from the wait() call.
Apart from the spurious wakeup issues (which should not affect this simple use most of the time), you should expect that code to always finish.
One thing you seem to be missing is that job.wait(); releases the lock, enabling the other synchronized block to be executed and notifyAll() to be called. At that point, wait wakes up and the main method exits.

Destroying a thread, having a never ending function int its run() method?

In my run() method of my Thread class, I am calling a never ending function.
I need the thread to run only for a specific duration.
Am not able to control the thread once its started, Is their any way to destroy it?
I have tried yield(), sleep(), etc...
PS - I cannot change the never ending function
From oracle Java Docs:
public void run(){
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
}
Your thread should check interrupted condition after each loop to see if it was interrupted. If you are calling a method that just does while(true){} then I am afraid there is no way interrupting it and stop() MUST never be called on a thread.
It is the programmers responsibility to make a long running method responsive to interrupts.
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html answers all your questions.. particularly section What should I use instead of Thread.stop?
Hope it helps
This could be too much, but this is how I would solve it, if you do not want to mess with Interrupt.
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadTest test = new ThreadTest();
test.go();
}
void go() throws InterruptedException{
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new LongRunnable());
if(!service.awaitTermination(1000, TimeUnit.MILLISECONDS)){
System.out.println("Not finished within interval");
service.shutdownNow();
}
}
}
class LongRunnable implements Runnable {
public void run(){
try{
//Simultate some work
Thread.sleep(2000);
} catch(Exception e){
e.printStackTrace();
}
}
}
Basically you are wrapping your runnable in a ExecutorServie and if it's not finished within the interval, you basically kill it - send the interruption to it.

Categories

Resources