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
I have a main thread that creates several threads using Executors
ExecutorService executor = Executors.newFixedThreadPool(4);
Each thread has long running jobs (some legacy code from another team) which might run for hours.
Now I want to shutdown from the main thread using
executor.shutdownNow()
And I want the threads to be able to stop immediately, how could I do that?
In the thread, say we have such code:
public void run() {
doA();
doB();
doC();
...
...
}
Now my issue is, even if I called shutdownNow, the running thread will run to the end then stop. I'd like to know how to stop and exit.
It's a slightly tricky situation indeed!
Can we make use of a hook that the JDK has provided in the form of ThreadFactory that is consulted when the associated thread pool is creating a thread in which your legacy task will run? If yes, then why not make your legacy code run in a daemon thread? We know that the JVM exits when the last non-daemon thread exits. So, if we make each thread that the thread pool uses to run your legacy tasks a daemon thread, there is a chance that we can make the shutdownNow() call more responsive:
public class LegacyCodeExecutorEx {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2, new DaemonThreadFactory());
executor.submit(new LegacySimulator());
Thread.sleep(1000);
executor.shutdownNow();
}
static class LegacySimulator implements Runnable {
private final AtomicLong theLong;
LegacySimulator() {
theLong = new AtomicLong(1);
}
#Override
public void run() {
for (long i = 10; i < Long.MAX_VALUE; i++) {
theLong.set(i*i);
}
System.out.println("Done!");
}
}
static class DaemonThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("Daemon Thread");
t.setDaemon(true);
return t;
}
}
}
If you play with setDaemon(true) line, you will see that this code either responds to the exit of the main thread (which is non-daemon) either immediately or takes its own sweet time to finish the task.
Is making your legacy-code-running threads daemon threads a possibility? If yes, you could give this a try.
You need to include a flag in the Runnable object instantiation that checks between tasks whether you need to stop or not.
public void run() {
if(timeToShutdown) return;
doA();
if(timeToShutdown) return;
doB();
/*etc*/
}
Threads in Java operate at a (relatively) low level. Short of directly shutting down the entire JVM, the only way to manually force the stop of a Thread is using Deprecated behavior from Java 1.0/1.1, which pretty much noone wants you to use.
I have a java program, which takes very long time to compile.
For testing purposes, I want to kill the program and restart it if compilation takes long duration.
Here is the simplified version of my code:
public class Main {
public static void main(String[] args) {
Thread foo = new Thread(new Foo());
while (true) {
foo.start();
while (true) {
if (needRestart()) {
foo.interrupt();
break;
}
}
}
}
}
foo.java looks a bit like this:
public class Foo implements Runnable {
// some code
public void run () {
try {
while (!Thread.currentThread().isInterrupted()) {
// some code
}
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
The problem is that the program crashes and throws an IllegalThreadStateException
If you need the full code, here it is: full code
Don't start foo thread in while(true) loop. You can start a Thread only once in it's life cycle.
Move foo.start(); above while(true)
Refer to oracle documentation page about Thread class start() method
public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
IllegalThreadStateException occurs when you try to change the state of your thread or when you try to again calling the start method on same thread once it is in running state.
But in your case if you want to interrupt your thread make it to go to sleep() in and when you want you to interrupt call notify() on that thread before it comes out of sleep automatically.
I must be missing something:
public class Test {
public static void main(String[] args) {
(new Thread(new Action())).run();
System.out.println("Blah");
}
}
class Action implements Runnable {
public void run() {
while (true) {
}
}
}
I make a thread that is supposed to be running a loop.
In my main thread I print "Blah".
However, it is never printed. Why not? If I made a separate thread, it shouldn't affect my main execution thread, right?
This machine has four cores.
Call start() instead of run() to start a thread.
Simply calling run() means a method call with infinite loop in the same main thread that will block the next statement written in main thread.
Have a look at Java Tutorial on Defining and Starting a Thread
I should be (new Thread(new Action())).start(); to start a thread but still it will create an infinite loop and the new started thread will never stop.
Try with Thread.currentThread().getName() to confirm it again as shown below:
public void run() {
System.out.println(Thread.currentThread().getName()); // output "main"
}
A Pictorial Representation of Thread Life-cycle along with it's methods
Because you are not invoking start(), you are calling directly the implementation method of the thread run(), thus no thread is started, code is just executed.
run() is the method called by the thread internal structure to execute the task, since it's just a normal method which doesn't have anything attached.
I have this issue I have no idea how to resolve and I'm at the brink of insanity. Programming, eh? :/
Anyway, I have a server which has a thread to send users all the info it needs to (which needs to run constantly) and another thread that awaits new server connections. My problem is once socket.accept() is called, the other thread doesn't execute.
So, to explain with code:
class Thread1 extends Thread {
public void run() {
while(true)
{
s=socket.accept();
}
}
class Thread2 extends Thread {
public void run() {
//do stuff
System.out.println("spam");
}
}
public static void main(String[] args)
{
Thread1 t1 = new Thread1();
t1.start();
t1.Thread2 t2 = t1.new Thread2();
t2.start();
}
}
Assume all other required member variables are present, no compile errors and connection functionality works fine. Just 'Thread2' executes only once.
So my question is, how do I resolve this problem?
Thanks in advance,
Tim.
I think you have a basic misunderstanding of threads. Let's see if we can clear that up.
Threads are simply another pipeline of execution. Think of them like tasks with a particular set of instructions. Once the task is done, the thread returns. Pretty simple idea, right?
In your example, Thread1 has an endless loop, which makes sense that it does run infinitely and does accept clients indefinitely.
However, Thread2 simply outputs some text and returns. There's nothing telling it to 'keep spinning'.
Within your main(), even though Thread2 is an inner class of Thread1 (which is kind of bad form to begin with, might I add) it doesn't actually force the thread to keep running.
You'll probably want to add a Queue to your server class that holds new sockets, and have Thread2 loop and check for entries.
Further Reading
Firstly, take a look at the Thread class. Its constructor takes a Runnable, so that's all you should be implementing when working with threads (i.e. class Foo implements Runnable and then new Thread(new Foo())).
If sockets are your fancy, perhaps some further reading on socket-server architecture and even about protocol design would be something you'd benefit from.
Some suggestions
never extend a Thread as it's a good way to confuse yourself. Never nest a Thread inside another Thread unless you really like confusion.
if you want to run a thread for each socket, then create a new thread for each socket in the loop.
Try the following (Note: You can add IOException handling code)
class SocketAcceptor implements Runnable {
public void run() {
while(true) {
Socket s=socket.accept();
SocketHandler sh = new SocketHandler(s);
new Thread(sh).start();
}
}
}
class SocketHandler implements Runnable {
final Socket s;
SocketHandler(Socket s) { this.s = s; }
public void run() {
System.out.println("New connection " + s);
s.close();
}
}
A better solution would be to use a Thread pool. e.g. An ExecutorService, but I would get this working first.
package com.nacre.test7;
public class TestDaemon {
public static void main(String[] args) throws InterruptedException {
MyDaemon dt=new MyDaemon();
if(dt.isDaemon()){
System.out.println(dt+"is demon thread");
Thread.sleep(1000);
System.out.println(" main thread is ending.");
}
}
}
package com.nacre.test7;
public class MyDaemon implements Runnable{
Thread thrd;
MyDaemon() {
thrd=new Thread(this);
thrd.setDaemon(true);
thrd.start();
}
public boolean isDaemon(){
return thrd.isDaemon();
}
public void run() {
try { while(true) {
System.out.print(".");
//Thread.sleep(100);
}
} catch(Exception exc) {
System.out.println("MyDaemon interrupted.");
}
}
}
In the above 2 class I have given breakpoint to each line in the program.I started debugging in eclipse editor and what I saw the control flow is ...........coming back to this below code after executing thrd.start() method of MyDaemon class
if(dt.isDaemon()){
System.out.println(dt+"is demon thread");
Thread.sleep(1000);
System.out.println(" main thread is ending.");
}
and noway the control is going to this below part
public void run() {
try { while(true) {
System.out.print(".");
Thread.sleep(100);
}
} catch(Exception exc) {
System.out.println("MyDaemon interrupted.");
}
What I knew is that when start() method is called , concurrently jvm calls run method by creating a new thread , my doubt is that why I am unable to see the execution of the run method while debugging
and how I am getting the following output
com.nacre.test7.MyDaemon#152b6651is demon thread
.......... main thread is ending.
Java Virtual Machine.
When you create Thread object and call start() on it gives the JVM a special instruction to create java thread,Here JVMdoes some deep magic that we cannot do in normal Java code. Via native calls it creates a new thread and causes the new thread to call the run() method.
According to Thread#start
Calling start() causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
Answer to
how I am getting the following output
com.nacre.test7.MyDaemon#152b6651is demon thread .......... main thread is ending.
The program is behaving perfectly fine. You cannot accept the main thread to be alive if the only thread it starts is a Daemon thread. Please read the source code / java doc of the Thread class.
Moreover, to your other question my doubt is that why I am unable to see the execution of the run method while debugging and
The run method execution is shown in the debug mode as below:
who is calling to the run() method?
The thrd.start() call in the MyDaemon constructor is causing it to happen.
In MyDaemon you instantiate a Thread object and pass it this as an argument. When a Thread object is started, it calls its run() method, and the default behaviour of the Thread.run() object is to call run() on its Runnable ... if one was supplied.
So:
the MyDaemon constructor creates a Thread object
the MyDaemon constructor calls thrd.start()
thrd.start() starts the new thread with a new stack
the new thread calls thrd.run()
thrd.run() calls run() on the MyObject instance
Note that steps 1 through 3 happen on the parent thread, and steps 4 through 5 happen on the child thread, either before or after the start() call returns in the parent thread.