Java threads - start() and run() - lost line in console - java

Why is another "TaskImpl run()" in Scenario 1 below missing ?
Scenario 1: if the line marked with 1. is before the line marked with 2. this is shown in the console:
TaskImpl run()
ThreadImpl run()
ThreadImpl run()
Finished
Scenario 2: If the line marked with 2. is before the line marked with 1. this is shown in the console:
TaskImpl run()
TaskImpl run()
ThreadImpl run()
ThreadImpl run()
Finished
My code :
public class ThreadTest {
public static void main(String[] args)
{
Thread t1 = new ThreadImpl();
Thread t2 = new Thread(new TaskImpl());
t1.start();
t2.start();
t1.run(); // 1.
t2.run(); // 2.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Finished");
}
}
class ThreadImpl extends Thread {
#Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("ThreadImpl run()");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class TaskImpl implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("TaskImpl run()");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

As you can see in the implementation of Thread#run the run method of the target (the Thread implementation/subclass which should be run in a thread) will only be called if target is not null:
#Override
public void run() {
if (target != null) {
target.run();
}
}
Now another info: If a thread has done its job it calls the private exit method which sets target to null (*):
private void exit() {
// [omitted code lines]
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
// [omitted code lines]
}
So if you called start on a Thread and it has done its job, then you can't call run again ... well you can, but I won't do much.
Now let's look at your first version of your code:
t1.start(); -> starts a thread; takes at least 2 seconds to finish
t2.start(); -> starts a thread; takes at least 1 second to finish
t1.run(); -> blocks main thread; takes at least 2 seconds to finish
t2.run(); -> called after `t1.run()` finished;
So as you can see, t2.run() will run at least 2 seconds after t2.start() because t1.run() blocks the method call. So t2 (from t2.start()) already finished and set target to null so t2.run() fails the target != null check and does "nothing".
Now the second version:
t1.start(); -> starts a thread; takes at least 2 seconds to finish
t2.start(); -> starts a thread; takes at least 1 second to finish
t2.run(); -> blocks main thread; takes at least 1 seconds to finish
t1.run(); -> called after `t2.run()` finished;
Here t2.run() can run before t2 from t2.start() could have finished his "sleep" so target is still set correctly.
And t1.run() also has no problem, because it directly calls the overriden run method of ThreadImpl, so it doesn't need to pass the check. And it wouldn't have a problem to pass it anyway, because t2.run() sleeps for 1 second, so t1 from t1.start() still sleeps for another second and his target is also still set.
That is why you get the "full" output.
I hope my explanation is clear and you understand the cause for the different output :).
(*) Please mind that this behavior my vary in other Java Environments. But the Oracles version and OpenJDK are doing that.

Related

Why does another thread get access to blocked object while synchronized section has not completed?

The message "main Thread" is printed before message "new Thread" though method with message "new Thread" is in syncronized section by object which include print* methods.
Test test = new Test();
new Thread(() -> {
try {
synchronized (test) {
Thread.sleep(5000);
test.printMessage();
}
} catch (InterruptedException e) {}
}).start();
Thread.sleep(1000);
test.printAnotherMessage();
}
public void printMessage() {
System.out.println("new Thread");
}
public void printAnotherMessage() {
System.out.println("main Thread");
}
}
In this example there is no synchronization between printAnotherMessage and the synchronized block that sleeps for 5 seconds, that's why main thread sleeps for 1 second and then prints main Thread without any waiting.
You probably intended to make printAnotherMessage a synchronized method.
In this case main thread will wait till the other thread finishes the execution of the block synchronized on test object.
There is no synchronisation on test.printAnotherMessage(); so it will be executed first assuming the timing is right. 4 seconds is a lot and should be enough.
synchronized (test) {
test.printAnotherMessage();
}
Thread.sleep is rarely a good option, though. A more proper way would be
Test test = new Test();
new Thread(() -> {
synchronized (test) {
test.printMessage();
test.notify();
}
}).start();
synchronized (test) {
test.wait();
test.printAnotherMessage();
}
I am playing a dangerous game here since I am assuming the main thread will enter the synchronized block and execute wait() before another thread is created and it enters its synchronized block. It's reasonable since creating a thread will take some time.
Test test = new Test();
new Thread(() -> {
try {
// a lot of time to let the main thread execute wait()
Thread.sleep(500);
synchronized (test) {
test.printMessage();
test.notify();
}
} catch (InterruptedException e) {}
}).start();
synchronized (test) {
test.wait();
test.printAnotherMessage();
}

Recursive calling of run method due to Thread.currentThread().run()

i am new to multithreading and trying to clear my basics.
public class SleepExample extends Thread {
private int counter = 0;
#Override
public void run() {
try {
counter++;
System.out.println("Value of counter "+counter);
System.out.println("Thread going in sleep "+Thread.currentThread().getName());
Thread.currentThread().run();
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("Thread out of sleep "+Thread.currentThread().getName());
}
public static void main(String[] args) {
new SleepExample().start();
new SleepExample().start();
Test test = new Test();
Thread t = new Thread(test);
t.start();
}
}
//another class implementing runnable
public class Test implements Runnable {
#Override
public void run() {
System.out.println("In Test runnable method");
}
}
When i run this code, my run method of SleepExample recursively call itself after below line
Thread.currentThread().run();
for thread belonging to SleepExample (Thread -0, Thread -1) and
it goes to run method of Test class for thread t.
I am unable to understand the usage of Thread.currentThread().run();
P.S. - I read its java doc and so i have implemented a runnable
I am unable to understand the usage of Thread.currentThread().run();
You are not supposed to call it directly. From Thread.start() You are supposed to use start() to call run() and that is it.
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.
You are already running in the run() so you should only call this if you can say why you are doing it, even then it will look like a bug or be plain confusing and I would suggest you use a loop instead.
When i run this code, my run method of SleepExample recursively call itself after below line
You have a method calling itself, so you should expect that to happen. There is nothing special to Thread in this regard. It is like any other recursive call in a method.

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

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.

sharing an Object between two thread running two different methods Android Java

I am new in java Android... I am trying to create two threads (named: Clean and Progress) that will run two different methods each method get the same object mix.while Clean will run a time consuming method that is part of mix's class (mix.TimeConsumingMethod();) I want Progress thread to monitor the progress of TimeConsumingMethod() by checking class variables such as mix.length and mix.framesClean
in progress I check to see mix.length > 0 if not I want Progress to wait over here my app crashes and in log CAT i get an error of:
09-20 10:37:32.773: E/AndroidRuntime(12030): java.lang.IllegalMonitorStateException: object not locked by thread before wait()
snippet of code invoking both threads:.
mix = new MixMaxMain();
progressThread = new Thread(new Runnable() {
#Override
public void run() {
Progress (mix);
}
},"Progress Thread");
CleanThread = new Thread(new Runnable() {
#Override
public void run() {
Clean (mix);
}
},"Cleaner Thread");
Log.d("STOP", "SEnding cleanThread AND progress Thread");
CleanThread.start();
progressThread.run();
snippet of Clean running time consuming method:
long time_start = SystemClock.elapsedRealtime();
mix.Run(Daudio,mu,sigSqr,c);
long time_end = SystemClock.elapsedRealtime();
snippet of Progress:
while(mix.length==0) {try {
Log.d("Progress", "Length is Zero");
Thread.sleep(1);//fails here!!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
Log.d("Progress", "Clean Has Started");
int totalProgressLen = (int)(mix.length+0.7*mix.length);
while(mix.done==false)
{
try {
progressThread.wait(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
progress.setProgress(mix.framsClean*256/totalProgressLen );
}
You get the IllegalMonitorStateException if the thread you're calling wait on does not own the lock on the monitor you're calling it on.
To do this, you can surround the wait() call in a synchronized block. In your case, it would be something like:
synchronized(progressThread){
progressThread.wait(50);
}
There is also a way to check for this with the holdsLock(Object obj) method, which will return true only if the current thread holds the monitor lock on the specified object.
For full details, take a look at the Java Documentation on wait() for an Object.

Method call from thread does not finish - How to end the thread - Workaround

I have a following code.
ReadWriteLock someLock = new ReentrantReadWriteLock();
Condition someCondition = someLock.writeLock().newCondition();
public someMethod() {
// do some stuff
someCondition.await(); //Lock here.
System.out.prinltn("This never prints");
}
public doSomeStuff() {
new Thread(new Runnable() {
#Override
public void run() {
try {
someMethod();
System.out.println("thread finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread is going to die");
}
}).start();
}
When the thread calls the method someMethod() it gets executed. But since there is an await() method on that function. It never ends / it does not print 'This never prints', unless its woken up by singnalAll(). But I want the thread to be finished once its executed.
I cannot refactor the whole thing. I just need a workaround to this problem. Its used in Swing application. So thread is important.
I think, this will do:
Thread thread =
new Thread(new Runnable() {
#Override
public void run() {
try {
someMethod();
System.out.println("thread finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread is going to die");
}
});
thread.start( );
final long reasonableTimeout = ...;
thread.join( reasonableTimeout );
// THIS WILL SHAKE IT UP
thread.interrupt( );
thread.join( );
// At this point, it is guaranteed that the thread has finished
I am not sure if I understood your question correctly but I think you want to start the someMethod() function and then make the caller exit without waiting for someMethod() to finish. This means you are basically branching your execution flow into two, one where the someMethod() running waiting for its due awakening and the other where the caller just continues on(which it will need to do if you want it to finish) after calling someMethod(). To do this you will have to run someMethod() in a separate thread. Something like this.
public doSomeStuff() {
new Thread(new Runnable() {
#Override
public void run() {
try {
new Thread(){
public void run(){
someMethod();
}
}.start();
System.out.println("thread finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread is going to die");
}
}).start();
}
Two ways you can sort this out.
1) Design your task with Interruption Policy
Do a defensive coding. If your task is interrupted by any means, the program should know how to deal with that.
2) Add a POISON PILL as in this example, Once you
public someMethod() {
while(condition predicate){
someCondition.await(TIME_OUT); //Lock here.
}
//ADD Poison pill here
System.out.prinltn("This never prints");
}
As Per Java Concurrency in Practice
When using condition waits (Object.wait or Condition.await):
1)Always have a condition predicate some test of object state that must hold before
proceeding;
2)Always test the condition predicate before calling wait, and again after returning from
wait;
3)Always call wait in a loop;
4)Ensure that the state variables making up the condition predicate are guarded by the lock
associated with the condition queue;
5) Hold the lock associated with the the condition queue when calling wait, notify, or
notifyAll; and
6)Do not release the lock after checking the condition predicate but before acting on it.

Categories

Resources