Why is Thread.sleep halting the main thread? [duplicate] - java

I created my own thread class implementing the Runnable interface. But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself. Is this just an issue within Eclipse or would I also have problem running this on a Server? Do I have to change something calling the thread so that the main method can terminate properly?
Here's my basic self-made thread:
public class OwnThread implements Runnable {
#Override
public void run() {
//do something
}
}
Here's the main class that won't terminate anymore:
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
When I debug it, the last called method is the exit()-method of the Thread-class. After going through these lines of code, the process goes on forever:
/**
* This method is called by the system to give a Thread
* a chance to clean up before it actually exits.
*/
private void exit() {
if (group != null) {
group.threadTerminated(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
Here's a screenshot of the thread that is running forever. The TestInterface class is where the main-method is located:

But every time I start running my own thread class as a new thread, the main class thread does not terminate anymore by itself.
This is somewhat wrong. Your program does not terminate because there exists at least one non-daemon thread that still is running. The rule is: A Java program is terminated if all non-daemon threads are terminated.
I modified your program to make this behavior clear:
public class OwnThread implements Runnable {
#Override
public void run() {
runForever();
}
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
runForever();
}
private static void runForever() {
while (true) {}
}
}
Running that will create two threads that will run forever. One is the main thread which is started by running the program, and the other is the thread started inside the main method:
Modifying the above code by removing the call to runForever in the main method ...
public static void main(String[] args) {
Thread thread = new Thread(new OwnThread());
thread.start();
}
... will result in a different thread picture:
Here the main thread is gone because it is terminated. But the other started thread is still running.
Side note: Suddenly another thread appears - DestroyJavaVM. Have a look at the post DestroyJavaVM thread ALWAYS running for more information.

The issue is indeed not caused by the multithreading logic itself, it is caused by Eclipse and the respective JVM. Running the exact same code in Netbeans or on an Tomcat 8 Server did not lead to any problems. A reinstallation of Eclipse did not solve the malfunction within the Eclipse framework, but having the certainty that the issue does not cause any trouble on a server is sufficient for me to close the case.
Thanks to Seelenvirtuose for the hints and his effort.

Related

What is happening in below code of threading?

Code:
public class ThreadTest {
public static void main(String[] args) {
MyImlementThread mit = new MyImlementThread();
Thread t = new Thread(mit);
t.start();
t = new Thread(mit);
t.start();
}
}
// MyImlementThread
class MyImlementThread implements Runnable {
public void run() {
System.out.println("This is implemented run() method");
}
}
/*
Output
This is implemented run() method
This is implemented run() method
*/
What happens here is the main thread starts two threads and exits. Each of the new threads writes a message to stdout, then ends. At that point since all the non-daemon threads have finished the JVM exits.
The posted code is confusing on account of it defining a Runnable but giving it a name ending in Thread.
A Thread object relates to an os-level thread, calling start on a Thread makes the code in the run method of the passed-in Runnable execute run on a separate thread from the one that called start.
The Runnable defines a task but doesn't specify how it runs. It could be passed into a specific Thread's constructor or submitted to an Executor or run by the current thread.
In this case the Runnable declared has no state, no instance variables are declared. Here two threads can execute the same Runnable without a conflict because there is no shared state. The printstream that writes to the console is synchronized, so the lines written by the threads each get written one at a time and don't get jumbled together.

Why does one thread stop the other thread from running?

I was going to use threads for each sound in a game engine I'm making. The problem is, whenever I make a new thread that has a while(true) statement, the other thread stops running.
I made a class to test this, and it only prints "goodbye", not "hello". I was wondering how to make the two threads run at the same time.
public class testor {
public static void main(String args[]){
testor test=new testor();
test.runTest();
}
class threadTest implements Runnable{
#Override
public void run() {
while(true){
System.out.println("goodbye");
}
}
}
public void runTest(){
threadTest test=new threadTest();
test.run();
while(true){
System.out.println("hello");
}
}
}
Since you are doing test.run(); you are only calling the method of that class but not starting the thread.
So in order to answer your question: there is no such a thread stopping the other thread from running? because you have only one Thread that is looping for ever and printing the message System.out.println("goodbye");
If that method is not looping for ever, it would return to the runTest method and then you would see the System.out.println("hello");
Summary:
For starting a Thread use the Thread::start method and not the run.
Using (new ThreadTest()).run() does not start a new Thread, but just invokes the run() method in the current thread.
To run the code in a separate thread do:
(new Thread(new ThreadTest())).start();
That's because you're not creating a new thread. Just naming a class something containing "thread" will not make it a thread, and a Runnable is no thread - it's a class like any other, with no special semantics or behaviour.
It's only special in that you can pass it to a Thread for execution.
public class Testor {
public static void main(String args[]){
Testor test=new Testor();
test.runTest();
}
class MyRunnable implements Runnable{
#Override
public void run() {
while(true){
System.out.println("goodbye");
}
}
}
public void runTest(){
Thread testThread = new Thread(new MyRunnable());
testThread.start();
while(true){
System.out.println("hello");
}
}
}
You should probably also adhere to the Java coding standards regarding your class and variable names if you do not want your code to look like an alien when combined with most other existing Java code.
Additionally, multithreading is more than just being able to start a new thread. You should also read about synchronisation issues - it's more complicated to do correctly than you might imagine.
Your run method contains an infinite loop.
The runTest() method creates the thread which means you'll have 2 execution stacks the main stack, and the runnable threadTest stack.
since you're running the thread method first that contains an infinite loop, you'll always get the output "good Bye".
Remove the infinite loop from run() method.

Use of Thread.currentThread().join() in Java

The following code is taken from an example in the Jersey project. See here.
public class App {
private static final URI BASE_URI = URI.create("http://localhost:8080/base/");
public static final String ROOT_PATH = "helloworld";
public static void main(String[] args) {
try {
System.out.println("\"Hello World\" Jersey Example App");
final ResourceConfig resourceConfig = new ResourceConfig(HelloWorldResource.class);
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, false);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
server.shutdownNow();
}
}));
server.start();
System.out.println(String.format("Application started.\nTry out %s%s\nStop the application using CTRL+C",
BASE_URI, ROOT_PATH));
//////////////////////////////
Thread.currentThread().join();
//////////////////////////////
} catch (IOException | InterruptedException ex) {
//
}
}
}
I understand what is going on apart from the use of Thread.currentThread().join();.
I'm a Java newbie and my understanding is that this will block the execution of the current thread (in this case, the main thread), and effectively deadlock it. i.e. it will cause the current (main) thread to block until the current (main) thread finishes, which will never happen.
Is this correct? If so, why is it there?
Thread.currentThread().join() blocks the current thread forever. In your example, that prevents the main from exiting, unless the program is killed, e.g. with CTRL+C on Windows.
Without that line, the main method would exit right after the server is started.
An alternative would have been to use Thread.sleep(Long.MAX_VALUE);.
It's a common misunderstanding that if the main thread exits, the program will exit.
This is only true if there is no non-daemon thread running. This may be true here, but usually it is better IMHO to make the background threads this main is "waiting" for non-dameon and let the main thread exit when it doesn't have anything to do. I have see developers put Thread.sleep() wrapped in an infinite loop. etc.
It's an example. It's just not a very good one.
They're trying to show you how to make a thread that runs forever.
Thread.currentThread().join(); is a statement that takes forever to complete. You're supposed to replace it with your own code that runs forever and, presumeably does something useful.

Java Timer hang issue

I've been scratching my head trying to figure out a hang issue with Java Timers. I was wondering if someone here could help out. Any help in diagnosing the issue is highly appreciated.
I have a simple program with three TimerTask classes (A, B, and Stopper). A and B run repeatedly every 400ms and 500ms respectively. Stopper task is scheduled to run at 2sec to shutdown everything. The timers fire as expected, and the run() methods of tasks execute as expected. However, once the stopper task executes, I expect the program to terminate, but it just hangs after printing "All tasks and timers canceled, exiting". I've tried using jstack to diagnose the problem but there is nothing obvious that indicates what, if anything needs to be released/stopped/canceled etc.
Here is my code:
package com.example.experiments;
import java.util.Date;
/**
* A test timer class to check behavior of exit/hang issues
*/
public class TimerTest {
TimerTest(){
}
class TaskA extends java.util.TimerTask {
TaskA(){
}
public void run() {
System.err.println("A.run() called.");
if (!running){
System.err.println("A: calling this.cancel().");
this.cancel();
return;
}
}
public boolean cancel(){
System.err.println("Canceling TaskA");
return super.cancel();
}
}
class TaskB extends java.util.TimerTask {
TaskB(){
}
public void run(){
System.err.println("B.run() called.");
if (!running){
System.err.println("B: calling this.cancel().");
this.cancel();
return;
}
}
public boolean cancel(){
System.err.println("Canceling TaskB");
return super.cancel();
}
}
private void start(){
this.running = true; // Flag to indicate if the server loop should continue running or not
final java.util.Timer timerA = new java.util.Timer();
final TaskA taskA = new TaskA();
timerA.schedule(taskA, 0, 400);
final java.util.Timer timerB = new java.util.Timer();
final TaskB taskB = new TaskB();
timerB.schedule(taskB, 0, 500);
class StopperTask extends java.util.TimerTask {
private java.util.Timer myTimer;
StopperTask(java.util.Timer timer){
myTimer = timer;
}
public void run(){
taskA.cancel();
taskB.cancel();
timerA.cancel();
timerB.cancel();
this.cancel();
myTimer.cancel();
System.err.println("Stopper task completed");
}
}
final java.util.Timer stopperTimer = new java.util.Timer();
final StopperTask stopperTask = new StopperTask(stopperTimer);
stopperTimer.schedule(stopperTask, 2*1000);
/** Register witjh JVM to be notified on when the JVM is about to exit */
java.lang.Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
System.err.println("shutting down...");
running = false;
taskA.cancel();
taskB.cancel();
timerA.cancel();
timerB.cancel();
stopperTask.cancel();
stopperTimer.cancel();
System.err.println("All tasks and timers canceled, exiting");
System.exit(0);
}
});
}
public static void main(String[] args) {
new TimerTest().start();
}
private boolean running = false;
}
As Karthik answered, remove the System.exit(0) and the program won't hang. I also agree with his remark about volatile keyword.
When the shutdown hooks are being ran, the JVM is already in its shutdown sequence which is guarded by a "static" monitor. Invoking the System.exit(0) method at that time will effectively put the JVM in a deadlock state.
Consider the following code example:
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
java.lang.Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
System.out.println(Thread.currentThread().getName());
System.exit(0);
}
});
}
It will also hang - the red square button means that the program is still running and as you can see in the console tab it printed out the name of the thread that ran the main method (main) and the name of the thread that runs the shutdown hook (Thread-0):
When you call the System.exit method, the method which will in turn be called is the Shutdown.exit method (I have omitted all the irrelevant source):
static void exit(int status) {
...
synchronized (Shutdown.class) { // "static" monitor mentioned in the first part of the post
sequence();
halt(status);
}
}
The sequence method runs all hooks and finalizers, while the halt method invokes the native halt0 method at which point the JVM finally exits, I suppose.
So this is what happens:
the main method is ran in the main thread, it prints the thread name and registers the shutdown hook
since there is no other code in it, the main thread dies
The DestroyJavaVM thread is started to execute the shutdown of the JVM
The DestroyJavaVM thread enters the synchronized block in the Shutdown.exit method and acquires the Shutdown.class monitor
The sequence method runs the registered shutdown hooks
The Thread-0 thread is started to run our shutdown hook registered in the main method
The Thread-0 thread prints its name and initiates another JVM shutdown via the System.exit method, which in turn tries to acquire the Shutdown.class monitor but it can't since it is already acquired
To sum up:
the DestroyJavaVM thread waits for the Thread-0 thread to finish
the Thread-0 thread waits for the DestroyJavaVM thread to finish
which is deadlock by definition.
Notes:
For additional info I recommend reading SO question How to capture System.exit event?
The linked code for system java classes is openjdk 6-b14 while mine is oracle 1.6.0_37 but I noticed no difference in the source.
I think that Eclipse doesn't show the thread states right, Thread-0 should definitely be in BLOCKED state since it tried to acquire a taken monitor (see here for code example). Not sure about the DestroyJavaVM thread, I won't assume without doing a thread dump.
Instead of System.exit(0) perform a return. Also, you should be marking your running variable volatile.

How to run a program forever in Java? Is System.in.read() the only way?

I took this code:
28 public static void main(String[] args) throws IOException {
29 HttpServer httpServer = startServer();
30 System.out.println(String.format("Jersey app started with WADL available at "
31 + "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...",
32 BASE_URI, BASE_URI));
33 System.in.read();
34 httpServer.stop();
35 }
Does line 33 "System.in.read()" means that it will block until there is input? Will this also work when starting the Java application using UNIX rc script - not manually started from a command line?
I'd like to write a Java application to listen for HTTP connections. The application will be started automatically when the system boots (using UNIX rc scripts). It means that the application will run continuously - theoretically forever, until purposefully stopped. What is the best way to implement this in the Java main() method?
It looks like a weird black magic but following does the trick in very elegant way
Thread.currentThread().join();
As a result the current thread, main for instance, waits on join() for thread main, that is itself, to end. Deadlocked.
The blocked thread must not be a daemon thread of course.
Leaving the main method in Java does not automatically end the program.
The JVM exists if no more non-daemon threads are running. By default the only non-daemon thread is the main thread and it ends when you leave the main method, therefore stopping the JVM.
So either don't end the main thread (by not letting the main method return) or create a new non-daemon thread that never returns (at least not until you want the JVM to end).
Since that rule is actually quite sensible there is usually a perfect candidate for such a thread. For a HTTP server, for example that could be the thread that actually accepts connections and hands them off to other threads for further processing. As long as that code is running, the JVM will continue running, even if the main method has long since finished running.
#Joachim's answer is correct.
But if (for some reason) you still want to block the main method indefinitely (without polling), then you can do this:
public static void main(String[] args) {
// Set up ...
try {
Object lock = new Object();
synchronized (lock) {
while (true) {
lock.wait();
}
}
} catch (InterruptedException ex) {
}
// Do something after we were interrupted ...
}
Since the lock object is only visible to this method, nothing can notify it, so the wait() call won't return. However, some other thread could still unblock the main thread ... by interrupting it.
while (true) { ... } should go on for a pretty long time. Of course, you'll have to figure out some way of stopping it eventually.
A common trick is to have some volatile boolean running = true, then have the main loop be while (running) { ... } and define some criteria by which a thread sets running = false.
Back to Threads, thats exactly what i wanted. Btw this awesome tutorial helped me a lot.
Main.java
public class Main {
public static void main(String args[]) {
ChatServer server = null;
/*if (args.length != 1)
System.out.println("Usage: java ChatServer port");
else*/
server = new ChatServer(Integer.parseInt("8084"));
}
}
and ChatServer.java Class extends a Runnable
public class ChatServer implements Runnable
{ private ChatServerThread clients[] = new ChatServerThread[50];
private ServerSocket server = null;
private Thread thread = null;
private int clientCount = 0;
public ChatServer(int port)
{ try
{ System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
start(); }
catch(IOException ioe)
{
System.out.println("Can not bind to port " + port + ": " + ioe.getMessage()); }
}
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
.... pleas continue with the tutorial
So in the main Method a Runnable is being instantiated and a new Thread as shown in
public void start() {
is being instantiated with the runnable.
That cases the JVM to continue executing the process until you quit the project or the debugger.
Btw thats the same as Joachim Sauer posted in his answere.
Java program terminates when there are no non-daemon threads running. All you need is to have one such running thread. You could do it using infinite loops but that would consume CPU cycles. The following seems like a reasonable way to do it.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {}); //submit a task that does what you want (in this case, nothing)
Also we can achieve the same with the ReentrantLock and call wait() on it:
public class Test{
private static Lock mainThreadLock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
System.out.println("Stop me if you can");
synchronized (mainThreadLock) {
mainThreadLock.wait();
}
}

Categories