Calling the run method in a thread - java

Here I have created the class Main and inside it a thread t1 had been start by sending it a runnable target. But since the thread has been started I believe the run() method, should run and call a.SetI(20) method. But the output gives as 0. Could somone please let me know the logic behind this.
public class _216 {
private int i;
public synchronized void setI(int i){
this.i=i;
}
public synchronized int getI(){
return i;
}
}
class Main{
public static void main(String[] args) {
final _216 a=new _216();
Runnable r=new Runnable(){
#Override
public void run() {
a.setI(20);
}
};
Thread t1=new Thread(r);
t1.start();
System.out.println(a.getI());
}
}

The 'logic behind this' is that the thread may not have executed yet when you do your print.

You should use t1.join() so that both main and this new thread will joined and later code will continue to print.
Here
Thread t1=new Thread(r);
t1.start();
t1.join()
System.out.println(a.getI());

You very well may be printing the result before the thread completes running.
At that point in time the threads may be running simultaneously.
Also recognize that i is never initialized until you call setI, consider hardcoding a default value.

Related

run() is never called by Thread.start() method

I have written a small multithreading program.
public class NewThread implements Runnable {
Thread t;
public NewThread() {
t = new Thread(this, "Thread created by Thread Class.");
System.out.println("Created by constuctor:"+ t);
t.start(); // This will call run, because t has context as this
}
#Override
public void run() {
System.out.println("run() method called.");
}
public static void main(String[] args) {
new NewThread();
}
}
This is how the book says to write it. However, I never get the run() method called statement in the console. Thus, it seems run() is never called. How can this be true?
Edit: Yes, it is bad practice to start a Thread from constructor, but that is not affecting the question. (I am getting so many down votes for that)
run() is never called by Thread.start() method
You code actually works on my system but that it doesn't work on your's, demonstrates that you have a classic race condition.
Inside of main(), the NewThread is constructed but the Java language says that it can reorder operations so that the operations in a constructor can happen after the constructor finishes. So it is possible that main() might finish before the NewThread has actually been started which can result in the JVM shutting down without running the thread.
Because of instruction reordering, you should never have a thread auto-start itself inside of the constructor. See: Why not to start a thread in the constructor? How to terminate?
You should instead do:
public NewThread() {
t = new Thread(this, "Thread created by Thread Class.");
System.out.println("Created by constuctor:" + t);
// don't start here
}
public void start() {
// start in another method
t.start();
}
public void run() {
System.out.println("run() method called.");
}
...
public static void main(String[] args) {
NewThread nt = new NewThread();
nt.start();
}
Since the NewThread has the same daemon status as your main thread (which is non-daemon) the JVM will not shutdown until nt.run() completes.

How does Java Threads work

I'm a Java learner, trying to understand Threads.
I was expecting output from my program below, in the order
Thread started Run Method Bye
But I get output in the order
Bye Thread started Run Method
Here is my code:
public class RunnableThread
{
public static void main(String[] args)
{
MyThread t1= new MyThread("Thread started");
Thread firstThread= new Thread(t1);
firstThread.start();
System.out.println("Bye");
}
}
class MyThread implements Runnable
{
Thread t;
String s= null;
MyThread(String str)
{
s=str;
}
public void run()
{
System.out.println(s);
System.out.println("Run Method");
}
}
In a multithreaded code there's no guarantee which thread will run in what order. That's in the core of multithreading and not restricted to Java. You may get the order t1, t2, t3 one time, t3, t1, t2 on another etc.
In your case there are 2 threads. One is main thread and the other one is firstThread. It's not determined which will execute first.
This is the whole point of Threads - they run simultaneously (if your processor has only one core though, it's pseudo-simultaneous, but to programmer there is no difference).
When you call Thread.start() method on a Thread object it's similar (but not the same, as it's starting a thread, and not a process and former is much more resource consuming) simultaneously starting another java program. So firstThread.start() starts to run paralel to your main thread (which was launched by your main method).
This line starts a main execution thread (like a zeroThread)
public static void main(String[] args)
Which you can reference, by calling Thread.sleep() for example.
This line
firstThread.start();
Starts another thread, but in order to reference it you use it's name, but you reference it from the main thread, which is running paralel to firstThread.
In order to get the expected output you can join these two threads, which is like chaining them:
This way:
public static void main(String[] args)
{
MyThread t1= new MyThread("Thread started");
Thread firstThread= new Thread(t1);
firstThread.start();
firstThread.join();
System.out.println("Bye");
}
join(), called on firstThread (by main thread) forces main thread to wait until the firstThread is finished running (it will suspend proceding to the next command, which is System.out.println("Bye");).
It appears that you seek the thread (and probably more than one) to run while main() waits for everything to finish up. The ExecutorService provides a nice way to manage this -- including the ability to bail out after a time threshold.
import java.util.concurrent.*;
class MyThread implements Runnable { // ... }
class MyProgram {
public static void main(String[] args)
{
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
// At this point, 3 threads teed up but not running yet
ExecutorService es = Executors.newCachedThreadPool();
es.execute(t1);
es.execute(t2);
es.execute(t3);
// All three threads now running async
// Allow all threads to run to completion ("orderly shutdown")
es.shutdown();
// Wait for them all to end, up to 60 minutes. If they do not
// finish before then, the function will unblock and return false:
boolean finshed = es.awaitTermination(60, TimeUnit.MINUTES);
System.out.println("Bye");
}
}
There is no specified order in which Java threads are accustomed to run. This applies for all threads including the "main" thread.
If you really want to see it working, try:
class RunnableThread
{
public static void main(String[] args)
{
MyThread t1= new MyThread();
Thread firstThread= new Thread(t1);
firstThread.start();
System.out.println("Thread Main");
for(int i=1;i<=5;i++)
{
System.out.println("From thread Main i = " + i);
}
System.out.println("Exit from Main");
}
}
class MyThread implements Runnable
{
public void run()
{
System.out.println("Thread MyThread");
for(int i=1;i<=5;i++)
{
System.out.println("From thread MyThread i = " + i);
}
System.out.println("Exit from MyThread");
}
}
When You start a Thread it will execute in parallel to the current one, so there's no guarantee about execution order.
Try something along the lines:
public class RunnableThread {
static class MyThread implements Runnable {
Thread t;
String s= null;
MyThread(String str) {
s=str;
}
public void run() {
System.out.println(s);
System.out.println("Run Method");
}
}
public static void main(String[] args) {
MyThread t1= new MyThread("Thread started");
Thread firstThread= new Thread(t1);
firstThread.start();
boolean joined = false;
while (!joined)
try {
firstThread.join();
joined = true;
} catch (InterruptedException e) {}
System.out.println("Bye");
}
}
This is not a thread start order problem. Since you're really only starting a single thread.
This is really more of an API Call speed issue.
Basically, you have a single println() printing "bye", which gets called as soon as the Thread.start() returns. Thread.start() returns immediately after being called. Not waiting for the run() call to be completed.
So you're racing "println" and thread initializaiton after "thread.start()", and println is winning.
As a sidenote, and in general, you might want to try to use ExecutorService and Callable when you can, as these are higher level, newer APIs.

Java thread not sleeping

I have this code(FULL SOURCE CODE) :-
class thread implements Runnable {
int i=0;
Thread t;
public void main(){
t= new Thread(this); //edited
for(i=0;i<=5;i++){
System.out.println(i);
}
}
public void run(){
try{
Thread.sleep(1000); //EDITED EARLIER, was: t.sleep(1000);
}
catch(InterruptedException e){
}
}
}
The thread is supposed to sleep for 1 second. But, the thread does not sleep at all. Where am I going wrong. Any help will be appreciated.
EDIT
I get the following error now ->
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:682)
at thread.main(thread.java:7)
The fundamental issue here is that you never start the thread. Your program's main is called on the default thread, you create an instance, and then do nothing with it.
If you want to start your thread, call t.start() (once). That will start your thread, which will run alongside the default thread the JVM created when running your program. Other than that both threads are running at the same time, they don't interact in your program, so you'll still see the numbers get printed out right away. Depending on what you're trying to do, you may want to move your loop from main to run.
(And yes, sleep is a static method which makes the current thread sleep. In Java, it's syntactically valid to call a static method through an instance reference, but it's a bad idea.)
So for instance, here's your class with minimal mods (note: your environment seems to create an instance and call the instance-specific main below, which is non-standard,but I left it alone as it seems to be what your environment does):
class ThreadExample implements Runnable
{
public void main(){
Thread t= new Thread(this);
t.start();
}
public void run(){
int i;
try{
Thread.sleep(1000);
for(i=0;i<=5;i++){
System.out.println(i);
}
}
catch(InterruptedException e){
}
}
}
Changes:
Use standard Java naming conventions for the class.
Make t a local variable in main.
Actually start the thread in main.
Move loop from main to run, after the sleep call.
Make i a local variable in run.
Call sleep via Thread rather than this.
Here's a more normal example with a static main:
class ThreadExample implements Runnable
{
public static void main(String[] args) {
Thread t = new Thread(new ThreadExample());
t.start();
}
public void run(){
int i;
try{
Thread.sleep(1000);
for(i=0;i<=5;i++){
System.out.println(i);
}
}
catch(InterruptedException e){
}
}
}
Live example with debug output
The sleep method in Thread is static, so it should be called Thread.sleep() and it actually makes the currently executing thread to sleep, not a specific thread instance that you call the method on.
Your code should look more like this. It has been a while since I've worked with threads so there might be minor errors people should feel free to edit.
class myThread implements Runnable
{
public void main(){
MyThread t= new MyThread();
t.start();
t.join();
}
public void run(){
try{
for(i=0;i<=5;i++){
System.out.println(i);
Thread.sleep(1000);
}
}
catch(InterruptedException e){
}
}
}

Wrapping a dead thread object in new thread object to restart it

I want to restart a thread for some use, for example in the below code.
class Ex13 implements Runnable {
int i = 0;
public void run() {
System.out.println("Running " + ++i);
}
public static void main(String[] args) throws Exception {
Thread th1 = new Thread(new Ex13(), "th1");
th1.start();
//th1.join()
Thread th2 = new Thread(th1);
th2.start();
}
}
When I'm executing the above program , some time i'm getting the output as
Running 1
Running 2
and some time i'm getting only
Running 1
After few run i'm getting only
Running 1 as output.
I'm totally surprise about this behavior. Can any one help me understand this.
if I put the join() then i'm getting only Running 1.
You reuse Thread instance, not Runnable. Thread overwrites its run() method to
public void run() {
if (target != null) {
target.run();
}
}
Where target is the Runnable that you give to the constructor. besides that, Thread has an exit() method that is called by the VM, and this method sets target to null (the reason is this bug). So if your first thread has the chance to finish its execution, its run() method is pretty much empty. Adding th1.join() proves it.
If you want to keep some state, you need to keep reference to your Runnable instance, not the Thread. This way run() method will not be altered.
I don't know why do you need this, but (please note that this code doesn't ensure that th1 is ALWAYS executed before th2, though) :
public static class Ex13 implements Runnable {
AtomicInteger i = new AtomicInteger(0);
CountDownLatch latch;
Ex13(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Running " + i.incrementAndGet());
latch.countDown();
}
}
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(2);
Ex13 r = new Ex13(latch);
Thread th1 = new Thread(r, "th1");
th1.start();
Thread th2 = new Thread(r);
th2.start();
latch.await(); // wait until both theads are executed
System.out.println("Done");
}
You want the incrementing of i to be synchronized, i.e.
public class Ex13 implements Runnable {
int i=0;
public void run() {
    System.out.println("Running "+ increment());
}
private synchronized int increment() {
return ++i;
}
}
The Java Tutorial has a very nice explanation of this given a very similar scenario. The problem is that incrementing a variable is not an atomic operation. Each thread needs to read the current state of i before setting it to the new value. Restricting access to incrementing the variable to one thread at a time assures you will get consistent behavior.
To see whats happening in the System.out.println you can also print the thread name:
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
I see you call the two threads with the same runnable object, so they will both use the same "i" variable, in order for you to get Running 1 Running 2 you need to synchronize "i"

How locks obtained in multithreading and on which object?

Class ThreadTest extends Thread {
public synchronized void run() {
}
public static void main(String args[])
{
Thread t1=new ThreadTest();
Thread t2=new ThreadTest();
t1.start();
t2.start();
}
}
I want to know in above scenario, how locks obtained and on which object?
Does above scenario valid?
As locks are obtained on a calling object in method synchronisation then in above scenario on which object lock will be obtained. One more question who(or which object) invokes the run method?
Thanks,
-Abhishek
t1 has the lock of the t1 instance.
t2 has the lock of the t2 instance.
But your example doesnt make much sense..
Maybe this example will help you:
public class Test extends Thread {
private String name;
public Test(String name) {
this.name = name;
}
public synchronized void run() {
System.out.println(name);
while(true)
{
// loop endless
}
}
public static void main(String args[])
{
Thread t1= new Test("t1");
Thread t2= new Test("t2");
t1.start();
t2.start();
}
}
The output is:
t1
t2
You have started both the threads, but it depends on JVM which thread it might execute, so depending upon the thread which starts executing will acquire the lock first and the second thread cant be on running state till the first thread stops.
but in your case as both are different thread instances they run parallel, as the lock is acquired at the object level.
Your example doesn't make that much sense, because locks are on a per-instance level, not on a per-class level as you might wanted to use them.
I think you got it wrong a bit. The thread is wrapping up the code that is executing commands. These executions often contain access on other objects. That is the point, where locking comes into the game. Each of these objects have a monitor that can be obtained by threads. However, only one thread can obtain the lock at a time. Thus, other threads are enqueued and can access object as soon as the current holder releases it, trivially by exiting a synchronized code block.
I think you might wanted to do something like this:
class ThreadTest extends Thread
{
private final Foo f;
public ThreadTest(Foo f,int i)
{
super(""+i);
this.f = f;
}
#Override
public void run()
{
f.bar();
}
public static void main(String args[])
{
Foo f = new Foo();
Thread t1 = new ThreadTest(f,1);
Thread t2 = new ThreadTest(f,2);
t1.start();
t2.start();
}
public static class Foo
{
public synchronized void bar()
{
System.out.print("hello form Thread ");
System.out.println(Thread.currentThread().getName());
}
}
}
Formal Definition
When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.
If what you want is to have only one thread execute at a time (What's the point) then you should call a static method and call that from inside your run(), there is only one static method for all object of a class
How do synchronized static methods work in Java?

Categories