Why does the following code throws an Exception?
class MyThread extends Thread
{
public static void main (String [] args)
{
MyThread t = new MyThread();
t.start();
System.out.print("one. ");
t.start();
System.out.print("two. ");
}
public void run()
{
System.out.print("Thread ");
}
}
Could you point me out to the JLS?
That's the contract of the 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.
Throws:
IllegalThreadStateException - if the thread was already started.
You can't start a thread twice.
As other responses say, you can't start a Thread twice. However, maybe what you want to do is to start 2 threads: in this case, just instanciate again your thread object:
MyThread t = new MyThread();
t.start();
System.out.print("one. ");
MyThread t2 = new MyThread();
t2.start();
System.out.print("two. ");
Related
I just started with the multithreading concepts of Java. I have written a small Java program but however, I am really not able to understand its behavior.
public class Mythread implements Runnable{
#Override
public void run() {
System.out.println("mythread: ");
Thread t=new Thread(this,"thread1");
for(int i=1;i<5;i++)
{
System.out.println("in for of myThread");
try {
t.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
System.out.println("in main thread");
Mythread mythread=new Mythread();
Thread thread=new Thread(mythread,"thread0");
thread.start();
for(int i=1;i<5;i++)
{
System.out.println("main class: "+i);
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Now when I execute the above program I see that when thread1 goes to sleep thread0 also goes to sleep.
t.sleep(1000);
Are thread1 and thread0 the same thread?
Also, I haven't started thread1 anywhere in my code then why does the thread go to sleep?
I am just a beginner to multithreading and referring Java The Complete reference book.
The Thread.sleep(...) method causes the current thread to sleep. It is a static method, not an instance method.
There is no safe way for one thread to force another thread to sleep.
You are also making other mistakes:
Creating a subclass of Thread is usually a mistake. The recommended way to do threading is to write a class that implements Runnable, and create instances of java.lang.Thread as your threads. Better still, use either a thread pool, fork-join pool or an ExecutorService instance.
In this:
Mythread mythread = new Mythread();
Thread thread = new Thread(mythread, "thread0");
you are actually using the mythread objects as (only) a Runnable.
The threads that you created in the run() method are never used ... because you never start them. But if you did, there would be a thread explosion ... because you are instantiating them with this as the Runnable, and the run() method just creates more threads.
There are a number of Java style violations ... starting with your choice of Mythread as a classname.
To answer your questions:
is thread1 and thread0 refers to same thread ?
No.
Also I haven't started thread1 anywhere in my code then why thread goes to sleep ?
In fact, it is thread0 that is going to sleep. If you change
System.out.println("in for of myThread");
to
System.out.println("in for of myThread: " + Thread.currentThread());
you will see ...
Thread.sleep is a class method, not an instance method. Effectively you are calling Tread.sleep(1000), which is a request on the threading classes to have the currently executing thread to sleep.
So although thread1 and thread2 are not the same thread, each thread requests to sleep for 1 second.
btw. any good IDE will tell you 'The static method sleep(long) from the type Thread should be accessed in a static way".
No, thread0 and thread1 are not the same thread. As said in previous answers, sleep method is static, it will put current thread to sleep. Since thread1 has never been to runnable state, there's no concept of it going in sleep state, it is your thread0 which is going to sleep.
For further reference on this you can refer here to get clear insights on the flow of the states of thread and creation of new thread from another thread.
I am learning how to use the join() in multithreading.I have a doubt in the following program.
When the main method first call the t1.join() does it put both the main thread as well as the t2 thread to wait or it is only the main thread that goes to wait?
public class App {
private int count = 0;
public void increment(){
count++;
}
public static void main(String[] args) {
App app=new App();
app.dowork();
}
public void dowork() {
Thread t1 = new Thread(new Runnable(){
public void run(){
for(int i=0;i<10000;i++){
increment();
}
}
});
Thread t2=new Thread(new Runnable(){
public void run(){
for(int i=0;i<10000;i++){
increment();
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("count is " + count);
}
}
You should read up a bit. Jenkov's multithreading walkthrough explains multithreading in detail without overloading you with information. To answer; you cause the main thread to wait until completion of the first thread and then wait for the completion of the second thread. But if you look closely, Consider the following:
You have 3 threads, the main thread, thread 1 and thread 2. The main thread starts the other two threads and then waits on thread 1. However both thread 1 and thread 2 are allowed to continue and only the main thread will be waiting until thread 1 is complete. If thread 2 would still be alive after completion of thread 1, the main thread will be waiting for thread 2.
Here only your main thread will be suspended until t1 thread finishes. After that also main thread will wait until t2 finishes.
When you t1.join() the main thread blocks and waits for thread t1 to finish. Thread t2 is unaffected. Once t1 completes the main thread will resume then execute t2.join() where it will wait for t2 to finish.
t1.join() causes the calling thread (presumably in this case main) to wait for t1. Similarly for t2.join()
This is my program in which a thread is started under the main method
public class ThreadTest {
public static void main(String args[]) throws InterruptedException {
Thread mainThread = Thread.currentThread();
Thread t1 = new Thread() {
public void run() {
while (true) {
System.out.println("Hi");
}
}
};
// t1.setDaemon(true);
t1.start();
}
}
How do I ensure that before the main thread is stopped all its child Threads are stopped?
I don't want to use the Daemon option. Is this possible?
In the main thread you can wait for the other Threads to be finished.
In a method executed by the main thread do (in your example the main method):
t1.join();
But remember that if t1 will never finish the main thread will never finish. So you migth want to use
join with a timeout.
t1.join(10000);
Use t1.join(), join() method makes main thread or any other thread, in with it was called, wait until this task will end and then continue it's work. In your case, your program Will never finish execution until call System.exit(0); or make t1.join(1000); // wait only for one second.
Just add t1.join() add the end of your method:
t1.start();
t1.join();
The main thread will wait until t1 is done.
If you have more than one child thread, suggest you to try the signal
t1.join();
System.out.println(mainThread.getName());
System.out.println(t1.getName());
main thread will wait until execution of t1 finishes
I tried to create a five threads, accordingly if one thread invokes the synchronized method on one object(objsyn in this case) then all other threads should wait till the thread finishes with the object. So the output should come from thread 1 to thread 5 in order. But the output is coming out of order.
class synctest extends Thread
{
public synchronized void display()
{
try{Thread.sleep(5000*((long)(Math.random())));}
catch(Exception e){}
System.out.println("From synchornized thread "+ Thread.currentThread().getName());
}
public synchronized void run()
{
synctest objsyn = new synctest();
objsyn.display();
}
public static void main(String args[])
{
synctest objsy = new synctest();
Thread t1 = new Thread(objsy,"Thread 1");
Thread t2 = new Thread(objsy,"Thread 2");
Thread t3 = new Thread(objsy,"Thread 3");
Thread t4 = new Thread(objsy,"Thread 4");
Thread t5 = new Thread(objsy,"Thread 5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
Thread execution order is not guaranteed. Synchronization make sure only one thread executing that block of code at a point of time, it doesn't care whether it is first thread (or) second thread.
If you want really execute a particular logic in order, then you don't really need threading. Remember that when you start a thread, it will be separate thread from main thread. May be answers for this question help you.
In this code, what does the two joins and break mean? t1.join() causes t2 to stop until t1 terminates?
Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread t2 = new Thread(new EventThread("e2"));
t2.start();
while (true) {
try {
t1.join();
t2.join();
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
What does this thread join code mean?
To quote from the Thread.join() method javadocs:
join() Waits for this thread to die.
There is a thread that is running your example code which is probably the main thread.
The main thread creates and starts the t1 and t2 threads. The two threads start running in parallel.
The main thread calls t1.join() to wait for the t1 thread to finish.
The t1 thread completes and the t1.join() method returns in the main thread. Note that t1 could already have finished before the join() call is made in which case the join() call will return immediately.
The main thread calls t2.join() to wait for the t2 thread to finish.
The t2 thread completes (or it might have completed before the t1 thread did) and the t2.join() method returns in the main thread.
It is important to understand that the t1 and t2 threads have been running in parallel but the main thread that started them needs to wait for them to finish before it can continue. That's a common pattern. Also, t1 and/or t2 could have finished before the main thread calls join() on them. If so then join() will not wait but will return immediately.
t1.join() means cause t2 to stop until t1 terminates?
No. The main thread that is calling t1.join() will stop running and wait for the t1 thread to finish. The t2 thread is running in parallel and is not affected by t1 or the t1.join() call at all.
In terms of the try/catch, the join() throws InterruptedException meaning that the main thread that is calling join() may itself be interrupted by another thread.
while (true) {
Having the joins in a while loop is a strange pattern. Typically you would do the first join and then the second join handling the InterruptedException appropriately in each case. No need to put them in a loop.
This is a favorite Java interview question.
Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread e2 = new Thread(new EventThread("e2"));
t2.start();
while (true) {
try {
t1.join(); // 1
t2.join(); // 2 These lines (1,2) are in in public static void main
break;
}
}
t1.join() means, t1 says something like "I want to finish first". Same is the case with t2. No matter who started t1 or t2 thread (in this case the main method), main will wait until t1 and t2 finish their task.
However, an important point to note down, t1 and t2 themselves can run in parallel irrespective of the join call sequence on t1 and t2. It is the main/daemon thread that has to wait.
join() means waiting for a thread to complete. This is a blocker method. Your main thread (the one that does the join()) will wait on the t1.join() line until t1 finishes its work, and then will do the same for t2.join().
A picture is worth a thousand words.
Main thread-->----->--->-->--block##########continue--->---->
\ | |
sub thread start()\ | join() |
\ | |
---sub thread----->--->--->--finish
Hope to useful, for more detail click here
When thread tA call tB.join() its causes not only waits for tB to die or tA be interrupted itself but create happens-before relation between last statement in tB and next statement after tB.join() in tA thread.
All actions in a thread happen-before any other thread successfully returns from a join() on that thread.
It means program
class App {
// shared, not synchronized variable = bad practice
static int sharedVar = 0;
public static void main(String[] args) throws Exception {
Thread threadB = new Thread(() -> {sharedVar = 1;});
threadB.start();
threadB.join();
while (true)
System.out.print(sharedVar);
}
}
Always print
>> 1111111111111111111111111 ...
But program
class App {
// shared, not synchronized variable = bad practice
static int sharedVar = 0;
public static void main(String[] args) throws Exception {
Thread threadB = new Thread(() -> {sharedVar = 1;});
threadB.start();
// threadB.join(); COMMENT JOIN
while (true)
System.out.print(sharedVar);
}
}
Can print not only
>> 0000000000 ... 000000111111111111111111111111 ...
But
>> 00000000000000000000000000000000000000000000 ...
Always only '0'.
Because Java Memory Model don't require 'transfering' new value of 'sharedVar' from threadB to main thread without heppens-before relation (thread start, thread join, usage of 'synchonized' keyword, usage of AtomicXXX variables, etc).
Simply put:
t1.join() returns after t1 is completed. It doesn't do anything to thread t1, except wait for it to finish.
Naturally, code following
t1.join() will be executed only after
t1.join() returns.
From oracle documentation page on Joins
The join method allows one thread to wait for the completion of another.
If t1 is a Thread object whose thread is currently executing,
t1.join() : causes the current thread to pause execution until t1's thread terminates.
If t2 is a Thread object whose thread is currently executing,
t2.join(); causes the current thread to pause execution until t2's thread terminates.
join API is low level API, which has been introduced in earlier versions of java. Lot of things have been changed over a period of time (especially with jdk 1.5 release) on concurrency front.
You can achieve the same with java.util.concurrent API. Some of the examples are
Using invokeAll on ExecutorService
Using CountDownLatch
Using ForkJoinPool or newWorkStealingPool of Executors(since java 8)
Refer to related SE questions:
wait until all threads finish their work in java
For me, Join() behavior was always confusing because I was trying to remember who will wait for whom.
Don't try to remember it that way.
Underneath, it is pure wait() and notify() mechanism.
We all know that, when we call wait() on any object(t1), calling object(main) is sent to waiting room(Blocked state).
Here, main thread is calling join() which is wait() under the covers. So main thread will wait until it is notified.
Notification is given by t1 when it finishes it's run(thread completion).
After receiving the notification, main comes out of waiting room and proceeds it's execution.
Hope it helps!
package join;
public class ThreadJoinApp {
Thread th = new Thread("Thread 1") {
public void run() {
System.out.println("Current thread execution - " + Thread.currentThread().getName());
for (int i = 0; i < 10; i++) {
System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
Thread th2 = new Thread("Thread 2") {
public void run() {
System.out.println("Current thread execution - " + Thread.currentThread().getName());
//Thread 2 waits until the thread 1 successfully completes.
try {
th.join();
} catch( InterruptedException ex) {
System.out.println("Exception has been caught");
}
for (int i = 0; i < 10; i++) {
System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
}
}
};
public static void main(String[] args) {
ThreadJoinApp threadJoinApp = new ThreadJoinApp();
threadJoinApp.th.start();
threadJoinApp.th2.start();
}
//Happy coding -- Parthasarathy S
}
The join() method is used to hold the execution of currently running thread until the specified thread is dead(finished execution).
Why we use join() method?
In normal circumstances we generally have more than one thread, thread scheduler schedules the threads, which does not guarantee the order of execution of threads.
Let's take a look at an example, create new project and copy the following code:
this is activity_main.xml code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btn_without_join"
app:layout_constraintTop_toTopOf="parent"
android:text="Start Threads Without Join"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btn_with_join"
app:layout_constraintTop_toBottomOf="#id/btn_without_join"
android:text="Start Threads With Join"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tv"
app:layout_constraintTop_toBottomOf="#id/btn_with_join"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
And this is code for MainActivity.java:
public class MainActivity extends AppCompatActivity {
TextView tv;
volatile String threadName = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
Button btn_without_join = findViewById(R.id.btn_without_join);
btn_without_join.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
withoutJoin();
}
});
Button btn_with_join = findViewById(R.id.btn_with_join);
btn_with_join.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
withJoin();
}
});
}
private void withoutJoin()
{
tv.setText("");
Thread th1 = new Thread(new MyClass2(), "th1");
Thread th2 = new Thread(new MyClass2(), "th2");
Thread th3 = new Thread(new MyClass2(), "th3");
th1.start();
th2.start();
th3.start();
}
private void withJoin()
{
tv.setText("");
Thread th1 = new Thread(new MyClass2(), "th1");
Thread th2 = new Thread(new MyClass2(), "th2");
Thread th3 = new Thread(new MyClass2(), "th3");
th1.start();
try {
th1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
th2.start();
try {
th2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
th3.start();
}
class MyClass2 implements Runnable{
#Override
public void run() {
Thread t = Thread.currentThread();
runOnUiThread(new Runnable() {
public void run() {
tv.setText(tv.getText().toString()+"\n"+"Thread started: "+t.getName());
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
tv.setText(tv.getText().toString()+"\n"+"Thread ended: "+t.getName());
}
});
}
}
}
This will be the result if you press first button (Start Threads Without Join):
And this will be the result if you press second button (Start Threads With Join):
let's say our main thread starts the threads t1 and t2. Now, when t1.join() is called, the main thread suspends itself till thread t1 dies and then resumes itself.
Similarly, when t2.join() executes, the main thread suspends itself again till the thread t2 dies and then resumes.
So, this is how it works.
Also, the while loop was not really needed here.