Some problems about invoking the start() method in the Thread class - java

I am a beginer in the concurrency field,and today i do some exercises in the join() method.
The code is :
public class ThreadJoinExample {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable(), "t1");
Thread t2 = new Thread(new MyRunnable(), "t2");
Thread t3 = new Thread(new MyRunnable(), "t3");
t1.start();
try {
t1.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
class MyRunnable implements Runnable {
#Override
public void run() {
System.out.println("Thread started:::"
+ Thread.currentThread().getName());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out
.println("Thread ended:::" + Thread.currentThread().getName());
}
and the questinon,for example,when "t1.start()",i think the t1 will invoke the run() method immediately,but it not true;when "t1.join()",the t1 will invoke the run() method,
i don not know the reason why causes it.My question are:
1. what happens when i invoke the start() method?
2. when thread t invoke the start() method,is the thread t will be pushed into the ready queue in the main memroy?

1. what happens when i invoke the start() method?
When you invoke start method, it just gets ready to execute your thread. It may or may not be immediate and is dependent on when scheduler schedules your thread and then jvm will run your run method.
2. when thread t invoke the start() method,is the thread t will be pushed into the ready queue in the main memory?
Yes that's right. It may or may not start immediately executing your thread. You could try in main method starting your thread, it might happen that you main thread completed execution while your thread is yet to begin.

what happens when i invoke the start() method?
Calling start() tells the thread to create the necessary system
resources and then execute the run() method asynchronously.
when thread t invoke the start() method, is the thread t will be pushed into the ready queue in the main memory?
Yes. The start() method tells the Java Virtual Machine that it needs
to create a system specific thread. After creating the system
resource, it passes the Runnable object to it to execute its run()
method.

Related

Only one thread appears to be active at once

I'm attempting to start another thread that branches from the main thread when thread.start() is called. But it appears to take the main thread in to the thread class. Here is minimum reproducible code of my issue. Thanks for looking.
public class Main {
public static void main(String[] args) throws InterruptedException {
ThreadWhileLoop threadWhileLoop = new ThreadWhileLoop();
//threadWhileLoop.run();
threadWhileLoop.start();
while (true){
Thread.sleep(1000);
System.out.println("Main Thread is doing its thing");
}
}
}
and here is the extended thread class
public class ThreadWhileLoop extends Thread {
#Override
public synchronized void start() {
super.start();
while (true){
System.out.println("ThreadWhileLoopIsRunning");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void run() {
super.run();
while (true){
System.out.println("ThreadWhileLoopIsRunning");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Expected output:
ThreadWhileLoopIsRunning
Main Thread is doing its thing
ThreadWhileLoopIsRunning
Main Thread is doing its thing
ThreadWhileLoopIsRunning
Main Thread is doing its thing
Actual output:
ThreadWhileLoopIsRunning
ThreadWhileLoopIsRunning
ThreadWhileLoopIsRunning
Don’t override start. The start method is used by the calling thread to get the new thread into a runnable state. There are very few good reasons to override it. In your posted code the whole program is running in the main thread.
What you need to do is override the run method in the new thread. Then have the main thread call start, which will cause the run method to execute in a separate thread.
(It would be better to create a Runnable than to override Thread. You can pass the Runnable into the Thread as a constructor argument. With this approach there is less temptation to tamper with the Thread object.)
You can check what thread is running with
System.out.println(Thread.currentThread().getName());
In another answer I have an example of starting a thread using a Runnable: https://stackoverflow.com/a/5915306/217324

How can ensure that one thread will be executed after its main thread is finished ?

I'd like to run a thread from the main thread , but I want this thread to be executed after the main thread is finished.
How should I do it ?
Can I pass the thread a reference to the main thread and call to join() method ?
The closest would be a shutdownHook,
Runtime.getRuntime().addShutdownHook(new Thread(){
...
});
But this would run will the process is still alive, once the process dies, thats it, you can't add any threads to a process that doesn't exist anymore.
You can use the Runtime.getRuntime() method for this. Here is an example:
public static void main(String[] args) {
.....
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){
public void run(){
// run when the main thread finishes.
}
}));
}
You can find more details about this in the documentation
You can artificially do this with basic thread objects as follows, although I would recommend using the other answers on shutdown hooks instead.
public static void main(String[] args) throws Exception {
// parametrizes with current thread
new Deferrable(Thread.currentThread());
System.out.println("main thread");
}
static class Deferrable extends Thread {
Thread t;
Deferrable(Thread t) {
this.t = t;
// optional
// setDaemon(true);
start();
}
#Override
public void run() {
try {
// awaits termination of given Thread before commencing
t.join();
System.out.println("other thread");
} catch (InterruptedException ie) {
// TODO handle
}
};
}
This will always print:
main thread
other thread
The typical synchronizer for this situation is a CountDownLatch. Have the spawned thread wait for the CountDownLatch prior to doing what it needs to, and have the main thread finish by calling CountDownLatch.countDown()
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(1); // will need only one countDown to reach 0
new Thread(() -> {
try {
latch.await(); // will wait until CountDownLatch reaches 0
// do whatever is needed
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
// do stuff
// end main thread
latch.countDown(); // will make the latch reach 0, and the spawned thread will stop waiting
}

Put join on Main thread unexpected behaviour

I wrote following Code :
public class ThreadDemo implements Runnable
{
private Thread t ;
private String threadName;
ThreadDemo(String threadName)
{
this.t = new Thread(this,threadName);
t.start();
}
public void run()
{
System.out.println("New thread has been started!!!" + t.getName());
}
public static void main(String args[])
{
new ThreadDemo("Thread-1");
Thread t = Thread.currentThread();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
new ThreadDemo("Thread-2");
}
}
So i have putted the join method on main thread . When i run it ,its execution never end.
Why it is so ? Why main thread doesn't end ? why it's running for infinite time.
The join() method waits for the thread that you call it on to finish. In your code, you are calling join() on the current thread - that is the same thread as you are calling it from. The main thread is now going to wait for itself to finish. That never happens, because it's waiting on itself...
You should not join the main thread, but the thread that you started instead.
ThreadDemo demo = new ThreadDemo("Thread-1");
try {
demo.t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Just another perspective to this code....
This code will hang even if you do not initialize the ThreadDemo objects
within the main program.
In short all this code can be reduced to saying the following statement,
Thread.currentThread().join() will never return.

How to interrupt BlockingQueue?

BlockingQueue.put can throw InterruptedException.
How can I cause the queue to be interrupting by throwing this exception?
ArrayBlockingQueue<Param> queue = new ArrayBlockingQueue<Param>(NUMBER_OF_MEMBERS);
...
try {
queue.put(param);
} catch (InterruptedException e) {
Log.w(TAG, "put Interrupted", e);
}
...
// how can I queue.notify?
You need to interrupt the thread that is calling the queue.put(...);. The put(...); call is doing a wait() on some internal condition and if the thread which is calling the put(...) gets interrupted, the wait(...) call will throw InterruptedException which is passed on by the put(...);
// interrupt a thread which causes the put() to throw
thread.interrupt();
To get the thread you can either store it when it is created:
Thread workerThread = new Thread(myRunnable);
...
workerThread.interrupt();
or you can use the Thread.currentThread() method call and store it somewhere for others to use to interrupt.
public class MyRunnable implements Runnable {
public Thread myThread;
public void run() {
myThread = Thread.currentThread();
...
}
public void interruptMe() {
myThread.interrupt();
}
}
Lastly, it is a good pattern when you catch InterruptedException to immediately re-interrupt the thread because when the InterruptedException is thrown, the interrupt status on the thread is cleared.
try {
queue.put(param);
} catch (InterruptedException e) {
// immediately re-interrupt the thread
Thread.currentThread().interrupt();
Log.w(TAG, "put Interrupted", e);
// maybe we should stop the thread here
}
You need to have a reference to the thread running the code with queue.put(), like in this test
Thread t = new Thread() {
public void run() {
BlockingQueue queue = new ArrayBlockingQueue(1);
try {
queue.put(new Object());
queue.put(new Object());
} catch (InterruptedException e) {
e.printStackTrace();
}
};
};
t.start();
Thread.sleep(100);
t.interrupt();
Calling put will wait for a slot to be free before it adds the param and flow can continue.
If you capture the thread that is running when put is called (ie, call Thread t1 = Thread.currentThread() before calling put) and then in another thread call interrupt on this (whilst the t1 is blocked).
This example has something similar whereby it takes care of calling interrupt after a given timeout.

Simple example to understand the concept of join() in Thread

I am studying the Threads in java.
I just want a simple example which explains the use of join() in Thread. I have seen this link..
Understanding join() method example
But still not able to understand the concept.
Can anybody explain me the concept of using the join() in Thread.
Any explanation retlated to this will be very helpful to me.
Thanks.
The simplest explanation I can come up is that join makes the caller thread wait for the completion of specified thread.
Say if you have a "main thread" and "thread A", if from the main thread you call A.join(), the main thread will wait until thread A finishes.
The java se manual page about concurrency should help you here: http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html
Thread.join() causes the current thread to wait for the thread you call join() on to die before it resumes execution.
Thread.join() blocks (does not return) until the thread you joined on has finished.
This is not the only way to wait for a thread to finish, but it is the most CPU-usage friendly way. Imagine if you had a loop like this (pseudocode):
while(!thread.isAlive())
{
Sleep(1);
}
This supposedly does the same thing... but, 1000 times per second, it will wake up, check the variable and go back to sleep. This means 1000 context switches (which are expensive) and the program will be slower as a result. This is called 'spinlocking' or 'busywaiting' and is frowned upon in programming as it consumes CPU for no reason.
I did some experiment and here is the result: 1. first started thread t3. 2. started t1 then 3. created t2 and t2 joinned the running thread t1.
By definition, t2 should wait for t1 to die and then it should start.
Observation: I called wait on t1, so t1 is paused but not died but I see then t2 is started why ?
public class TestThreadJoin {
public static void main(String[] args) {
final Thread t3 = new Thread(new Runnable() {
public void run() {
System.out.println("R3");
}
});
t3.start();
final Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("R1 before");
try {
perform();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("R1 after");
}
private void perform() throws InterruptedException {
synchronized(this){
wait(5000);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("R2");
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t2.start();
}
}

Categories

Resources