I am looking for some more knowledge about java main method public static void main(String[] args) .When JVM call main method it creates Main thread and the whole program is get executed in this Main thread until some user thread explicitly get started in its own stack.
My question is that is it possible to start main thread from some other main method?
Its better if someone can give me some reference about main thread.
The main thread is just a concept, it's a name for the thread that starts your app, this thread is not special in any way (other than not being a daemon thread) so you can easily create new threads that are not daemons also and call another main method on them.
There isn't anything special about being the main thread, it's just the first thread to be started.
As far as my knowledgee, main thread is started by the JVM and the other threads started by the user are the sub-thread of the main thread in that thread group.
class FirstApp {
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
SecondApp.main(args);
}
}).start();
Starts a new thread and calls the main method of another application. Works fine. But they run both in the same process.
However, if you want to do it as if it was executed from command line (in another (separate) process), you can also do something like this:
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
StringBuilder cmd = new StringBuilder();
cmd.append(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java ");
for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
cmd.append(jvmArg + " ");
}
cmd.append("-cp ").append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(" ");
cmd.append(Main2.class.getName()).append(" "); // Main2 is the main class of the second application
for (String arg : args) {
cmd.append(arg).append(" ");
}
Runtime.getRuntime().exec(cmd.toString());
// continue with your normal app code here
}
}
I took the second code mostly from How can I restart a Java application?
Related
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.
I am not able to understand the behavior of this below program ,well as i can see that there is no thread reference is there in which we can pass the myThread reference but still the program is executing please advise is it the main thread which is executing this program
class MyThread extends Thread
{
public static void main(String [] args)
{
MyThread t = new MyThread();
t.start();
System.out.print("one. ");
System.out.print("two. ");
}
public void run()
{
System.out.print("Thread ");
}
}
the output is
one. two. Thread
This program consists of two threads.
The main() thread which is started when you start the program
The MyThread thread which you start from main()
This call:
t.start();
...will start a 2nd thread, which will run the code in the MyThread class's run method.
Because when you call t.start() , the run() method (you override) is executed,
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
The start() method :
- Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
I've always found the practice of letting your Main class extend something (in example code) dubious at best as it is unclear for beginners that when the main method is called there actually is no instance yet of the Main class (in this case the MyThread class).
So I've rewritten the example to make it more clear as to what happens:
public class Main
{
public static void main(String [] args)
{
// main gets called when starting your program (which is a thread created by the JVM for free)
MyThread t = new MyThread(); // You create a new Thread here
t.start(); // You start the thread
System.out.print("one. "); // In the mean time, the main thread keeps running here
System.out.print("two. ");
}
public static class MyThread extends Thread {
#Override
public void run()
{
System.out.print("Thread ");
}
}
}
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.
Here is the Example Code:
public class HelloRunnable implements Runnable {
#Override
public void run() {
System.out.println("Run Entered");
}
public static void main(String args[]) {
Thread obj=new Thread(new HelloRunnable());
obj.start();
System.out.println("ABC");
}
}
Output:
ABC
Run Entered
Why ABC before the run()'s code?
Even I create 3 threads. But still ABC print first;
obj.start();
obj1.start();
obj2.start();
Really I tried to search about this, but unable to find the query for this.
Simply because the HelloRunnable.run method is executed in another thread than the one printing ABC. They execute concurrently, that's the point of threads. Therefore, any of the two may access a certain resource, like the stdout, before the other.
When you call obj.start(), internally it spawns a new thread. So at that stage, you have 2 threads in your process, One is main thread, and one is new thread.
Each thread needs cpu to execute, and that's driven by cpu scheduling queue. If main thread hold the cpu, then out put will be what you saw. If context switch happens just after the statement obj.start();then cpu is given to new thread, Then you will see the thread output first and then the main output.
So the behavior is undeterministic as you can never predict that after which statement the context switch will happen.
Also what you see in the code is not what gets executed at the cpu. At the cpu assembly is executed. So even if you say that you were executing obj.start(), but you can never say on which assembly instruction you really were when context switch happened.
Would be reverse or like this. You started a "Thread". You are running on the main thread. So you have two independent running code. How do you guarantee that one will finish its work before the other ?
Try to sleep main thread after starting other threads. With
Thread.sleep(2000);
Then other threads would finish their works. You can see that ABC printed last.
public class HelloRunnable implements Runnable {
#Override
public void run() {
System.out.println("Run Entered");
}
public static void main(String args[]) {
Thread obj=new Thread(new HelloRunnable());
obj.start();
try{
Thread.sleep(2000);
}
catch(Exception e){}
System.out.println("ABC");
}
}
They are parallel works so you don't have a guarantee that ABC printed lastly or firstly. Depends on the machine CPU, works you have.
If I were to write a main class that creates a thread, is it possible that the thread created by the class outlives the main() of the class that created it.
In a way it seems possible because, I could make the newly created thread sleep for an hour , so the new stack goes into blocked state, leaving the original main stack free for execution, the main stack executes and has nothing else to do, while the new stack is still in blocked state.
But on the other hand, there is this statement in Java that everything starts and ends with the main() method.
Please let me know which one is correct
Yes, but only if the thread you create isn't a daemon thread. This (non-daemon) is actually the default.
there is this statement in Java that everything starts and ends with the main() method.
This is not true. You have
import java.io.PrintStream;
class Main {
static {
System.out.println("0) Printed before main");
}
public static void main(String... args) {
System.out.println("1) Printed in main");
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("3) Printed long after main");
}
});
throw new RuntimeException() {
public void printStackTrace(PrintStream ps) {
System.err.println();
System.out.println("2) Printed after main");
}
};
}
}
prints
Exception in thread "main"
0) Printed before main
1) Printed in main
2) Printed after main
3) Printed long after main
This is not only possible, but the normal state of affairs when you write a Swing app. You're not supposed to create Swing components outside the Swing thread, so the main thread queues up a task to create the UI in the Swing thread and then exits.