Why does the below program output 11 and not 12?.
Does not the thread use the same instance variables? Please explain?
public class Tester extends Thread {
private int i;
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.print(t.i);
t.start();
System.out.print(t.i);
}
public void run(){ i++;}
}
The above code compiles fine. i is defaulted to 0 value on construction of object.
In happens before relation concept all code executed prior to start of thread is completed.
The concept is - instance variables are shared across multiple threads - here there are two threads running - the main thread and the Tester thread. So i should shared with both threads? - if i is shared and if happens-before relation is maintained before starting Tester thread then the value of incremented i should be visible to the Tester thread?
Give to your new thread the time to increase the variable, try with
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.println(t.i);
t.start();
try {
Thread.sleep(1000); // 1 sec
} catch (Exception ex) {}
System.out.println(t.i);
}
The only problem in your code is that you print the t.i value and do not wait after t.start(), you print the value before the thread increases it.
The instance variable can be accessed by multiple threads if you let them, for example making it public, or by any other means.
In your code this is what happens: The Tester thread t will access it's own variable, and you will access also that same variable from the main thread. For the moment when you ask it to print the value, it may print any value by which the Testet thread t is at the moment.
When the main thread calls the run method it will execute in the main thread, effectively increasing the value of the field to 1 (as 0 is the default). Afterwards when you call the method start it will start the separate thread and the Java VM will call the method run, then again the field gets incremented, this time from 1 to 2.
So, I would expect that the output is 1 and then, possible 1 or possibly 2 depending on whatever there was time for the thread to execute before you asked to print the value from the main thread.... the exact result you get depends on your machine, in another computer it can be another tale. This depends on the CPU, the operating system, the available memory and other things.
As dash1e suggested in his answer, you can use Thread.sleep(1000); to make the main thread wait while the Tester thread t executes on background. This greatly increases the likelihood that the Tester thread t will have updated the value of the field before the main thread asks for it to print it. That said, I want to left clear that using Thread.sleep(1000); to wait for a task to complete is not good enough by itself... if you want to, you can put a call to Thread.sleep inside a while where you verify if a certain criteria has been met, that's known as an spinning.
The fact that you can print the value of the field form the main thread demostrates that you can access it from another thread. And that is a good thing, because you want your thread to communicate... somehow.
It is ok to access it because it is only an int, and an int cannot be in an invalid state, so there is no need sync the access. Although you may get an not up-to-date value, and it will change on background, so it isn't very reliable.
If you want a value that can only be acceded by a single thread, and that exists idependly for each thread, then take a look to ThreadLocal.
The main answer that I was looking for was in terms of happens-before: Concept detailed below:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility
So it says in the docs -
a) that before a thread starts - all statements prior to it are completed
b) all statements in the thread execution are completed at the termination of the new thread.
Going with the above understanding - i should be all the time visible to the new thread started. And this it should be - at all times, on all systems - so when start is called and a new thread is launched then it should always see i as 1.
But, the time we are printing the i value is getting executed by the main thread - not by the Tester thread. So even though the new Tester thread may see the value as 1 and increment it as 2 - the execution in main does not reflect it because i++ is not an atomic operation.
Now suppose we try and make the int as :
private volatile int i;
volatile guarantees happens-before relationship for not only the specific variable but also statement until it.
The println of main thread that gets executed may get executed before the increment even began. So we may see 11 getting printed, even after making the variable volatile. Similar case exists for making the variable an AtomicInteger.
The run method when invoked will see the incremented value:
System.out.println("i "+ i.incrementAndGet());
But not the main thread. Visibility of data in the run method / main method differs.
Instance variable used is same for both threads executing.
You have started the thread, but have not wait for it to stop. Use t.join() to wait for finish. And, yes, you have thread synchronization issue, but that's another issue.
public class Tester extends Thread {
private int i;
public static void main(String[] args) throws InterruptedException {
Tester t = new Tester();
t.run();
System.out.println(t.i);
t.start();
t.join();
System.out.println(t.i);
}
public void run() {
i++;
}
}
I your code:
public class Tester extends Thread {
private int i;
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.print(t.i);
t.start();
System.out.print(t.i);
}
public void run(){ i++;}
}
You call t.run() and t.start(). There are 2 thread are running t.run() thread and t.start() thread.
In that i variable you share between 2 thread that is not synchronous.
Therefore sometime value of i variable is not update between threads.
You can synchronous by using volatile keyword
private volatile int i;
Or synchronise code segment increases value of i
public void run(){
synchronized(this){
i++;
}
}
Related
I searched "java race condition" and saw a lot of articles, but none of them is what I am looking for.
I am trying to solve the race condition without using lock, synchronization, Thread.sleep something else. My code is here:
public class Test {
static public int amount = 0;
static public boolean x = false;
public static void main(String[] args) {
Thread a = new myThread1();
Thread b = new myThread2();
b.start();
a.start();
}
}
class myThread1 extends Thread {
public void run() {
for (int i = 0; i < 1000000; i++) {
if (i % 100000 == 0) {
System.out.println(i);
}
}
while(true){
Test.x = true;
}
}
}
class myThread2 extends Thread {
public void run() {
System.out.println("Thread 2: waiting...");
while (!Test.x) {
}
System.out.println("Thread 2: finish waiting!");
}
}
I expect the output should be:
Thread 2: waiting...
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
Thread 2: finish waiting!
(Terminated normally)
But it actually is:
Thread 2: waiting...
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
(And the program won't terminate)
After I added a statement to myThread2, changed
while (!Test.x) {
}
to
while (!Test.x) {
System.out.println(".");
}
The program terminate normally and the output is what I expected (except those ".')
I know when 2 threads execute concurrently, the CPU may arbitrarily switch to another before fetch the next instruction of machine code.
I thought it will be fine if one thread read a variable while another thread write to the variable. And I really don't get it why the program will not terminate normally. I also tried to add a Thread sleep statement inside the while loop of myThread1, but the program still will not terminate.
This question puzzled me few weeks, hope any one can help me please.
Try to declare x as volatile :
static public volatile boolean x = false;
Test.x isn't volatile and thus might not be synchronized between threads.
How the print-command in the second loop affects the overall behavior can't be predicted, but apparently in this case it causes x to be synchronized.
In general: if you omit all thread-related features of java, you can't produce any code, that has a well defined behavior. The minimum would be mark variables that are used by different threads as volatile and synchronize pieces of code, that my not run concurrently.
The shared variable x is being read and written from multiple threads without any synchronisation and hence only bad things can happen.
When you have the following,
while (!Test.x) {
}
The compiler might optimise this into an infinite loop since x (the non volatile variable) is not being changed inside the while loop, and this would prevent the program from terminating.
Adding a print statement will add more visibility since it has a synchronised block protecting System.out, this will lead into crossing the memory barrier and getting a fresh copy of Test.x.
You CAN NOT synchronise shared mutable state without using synchronisation constructs.
Much more better would be a LOCK object you may wait in Thread2 and send a notificytion in thread 1. You are currently active waiting in Thread2 and consume a lot of CPU resources.
Dummy code example:
main() {
Object lock = new Object();
Thread2 t2 = new Thread2(lock);
t2.start();
Thread1 t1 = new Thread1(lock);
t1.start();
...
}
class Thread1 {
Object lock = null;
public Thread1(Object lock) {
this.lock = lock;
...
}
public void run() {
...
synchronized (lock) {
lock.notifyAll();
}
}
} // end class Thread1
// similar Thread2
class Thread2 {
... constructor
public void run()
{
System.out.println("Thread 2: waiting...");
synchronized(lock) {
lock.wait();
}
System.out.println("Thread 2: finish waiting!");
}
....
This construct does not consume any CPU cycles without doing anything in "Thread2". You can create a custom number of "Thread2" instances and wait till "Thread1" is finished. You should "only" start all "Thread2" instances before "Thread1". Otherwise "Thread1" may finish before "Thread2" instances are started.
What you are really asking is, "Why does my program work as expected when I add a call to println()?"
Actions performed by one thread aren't generally required to be visible to other threads. The JVM is free to treat each thread as if it's operating in its own, private universe, which is often faster than trying to keep all other threads updated with events in that private universe.
If you have a need for some threads to stay up-to-date with some actions of another thread, you must "synchronize-with" those threads. If you don't, there's no guarantee threads will ever observe the actions of another.
Solving a race condition without a memory barrier is a nonsensical question. There's no answer, and no reason to look for one. Declare x to be a volatile field!
When you call System.out.println(), you are invoking a synchronized method, which, like volatile, acts as a memory barrier to synchronize with other threads. It appears to be sufficient in this case, but in general, even this is not enough to guarantee your program will work as expected. To guarantee the desired behavior, the first thread should acquire and release the same lock, System.out, after setting x to true.
Update:
Eric asks, "I am curious how volatile work, what has it done behind. I thought that everything can be created by addition, subtraction, compare, jumping, and assignment."
Volatile writes work by ensuring that values are written to a location that is accessible to all reading threads, like main memory, instead of something like a processor register or a data cache line.
Volatile reads work by ensuring that values are read from that shared location, instead of, for example, using a value cached in a register.
When Java byte codes are executed, they are translated to native instructions specific to the executing processor. The instructions necessary to make volatile work will vary, but the specification of the Java platform require that whatever the implementation, certain guarantees about visibility are met.
I'm running a multi threaded program and the problem I have is that it produces different output each time it's run. Here's my code.
package com.mypackage;
public class TryThreads extends Thread{
int i=-10;
public static void main(String arg[]){
TryThreads tt1=new TryThreads();
TryThreads tt2=new TryThreads();
tt1.start();
tt2.start();
}
public synchronized void run() {
for(;i<=10;i++) {
System.out.println(TryThreads.getThreadName()+" "+i);
}
}
static String getThreadName() {
Thread t1=new Thread();
return t1.getName();
}
}
whenever I run the code it produces different output, can anybody help me out with this?
Let's sum up you code:
You are starting two threads.
Your threads loop from i = -10 to 10
Each loop calls a static method.
The static method creates a NEW thread each time and returns the
name of the NEW thread.
The caller thread outputs the name of each NEW thread plus the index
variable i.
When you are running your code you are going to create 2 + 42 Threads (index 0 to 43).
First thing that makes no sense is that you are synchronizing the run() method which is useless because both of the two threads are working on their own object. The different output is as expected because you cannot predict when one of the two threads is active and iterating over the static getThreadName() method. It could be that Thread1 is doing 3 iterations before Thread2 is doing one. But it could also be that Thread2 is doing five iterations before Thread1 makes one.
This behaviour is called race confitions. It is up to the VM/OS to handle the threads if you don't manage them in you application code.
It is normal but if you do:
public static void main(String arg[]){
TryThreads tt1=new TryThreads();
TryThreads tt2=new TryThreads();
tt1.start();
tt2.start();
tt1.join();
tt2.join();
}
Then you should get first thread 1 name and then thread 2 name. It is normal that you get different results. Usually you store thread results in for example different class variable making sure that everything is thread safe. For example making method that is writing data to some variable synchronized. There is many ways to do it. But in your case you get that result cause you do not join threads to the main thread. It would be more noticeable if you spawn more threads doing much more than printing thread name.
Here is nice article about threads -> THREADS
But if you actually ask why your threads name are different then it is normal they are generated when you create new thread...
E.g. method public static void sleep(long millis). This method causes current thread to sleep, but how does it know, which thread is current? Static methods are object-independent and belong to class, so how does this mechanism work?
This method causes current thread to sleep, but how does it know, which thread is current?
The current thread is managed by the underlying operating system (or the threading system). The underlying (system dependant) thread implementation provides a handle to the current thread:
In case of POSIX threads, there is the API call pthread_self() which returns the thread ID of the currently executing thread. You can think of Thread.currentThread() eventually calling this C function and wrap the thread ID in a Java Thread object which is then returned.
In case of MS Windows, there is the API call GetCurrentThread() which returns the Windows Handle of the currently executing thread. Again, you can think of Thread.currentThread() eventually calling this C function and wrap the Handle in a Java Thread object which is returned.
native methods are special. They have access beyond the Java API.
In this case, to the current thread. You can't use this method to put another thread to sleep - the other thread will have to do this by itself (but you can send it a message, obviously).
This method is always called for the current / executing thread.
It means your current thread will go in sleep mode for a perticlar time.
Ex: if i will write Thread.sleep(1000) thread will go to sleep state for 1000 miliseconds.
We use this menthod mainly to interchange between the thread.In short, it will give chance to another thread for execution.
The current thread is the one actually executing the piece of code. As simple as that.
For instance:
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
System.out.println("Before sleeping!");
Thread.sleep(10000);
System.out.println("After sleeping!");
}
}
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
System.out.println("Main thread!");
}
May output something like:
Before sleeping! // t1
Main thread! // main
Before sleeping! // t2
After sleeping! // t1
After sleeping! // t2
I have a loop that doing this:
WorkTask wt = new WorkTask();
wt.count = count;
Thread a = new Thread(wt);
a.start();
When the workTask is run, the count will wt++ ,
but the WorkTask doesn't seems change the count number, and between the thread, the variable can't share within two thread, what did I wrote wrong? Thanks.
Without seeing the code for WorkThread it's hard to pin down the problem, but most likely you are missing synchronization between the two threads.
Whenever you start a thread, there are no guarantees on whether the original thread or the newly created thread runs first, or how they are scheduled. The JVM/operating system could choose to run the original thread to completion and then start running the newly created thread, run the newly created thread to completion and then switch back to the original thread, or anything in between.
In order to control how the threads run, you have to synchronize them explicitly. There are several ways to control the interaction between threads - certainly too much to describe in a single answer. I would recommend the concurrency trail of the Java tutorials for a broad overview, but in your specific case the synchronization mechanisms to get you started will probably be Thread.join and the synchronized keyword (one specific use of this keyword is described in the Java tutorials).
Make the count variable static (it looks like each thread has its own version of the variable right now) and use a mutex to make it thread safe (ie use the synchronized instruction)
From your description I came up with the following to demonstrate what I perceived as your issue. This code, should output 42. But it outputs 41.
public class Test {
static class WorkTask implements Runnable {
static int count;
#Override
public void run() {
count++;
}
}
public static void main(String... args) throws Exception {
WorkTask wt = new WorkTask();
wt.count = 41;
Thread a = new Thread(wt);
a.start();
System.out.println(wt.count);
}
}
The problem is due to the print statement running before thread had a chance to start.
To cause the current thread ( the thread that is going to read variable count ) to wait until the thread finishes, add the following after starting thre thread.
a.join();
If you are wishing to get a result back from a thread, I would recommend you to use Callable
interface and an ExecutorSercive to submit it. e.g:
Future future = Executors.newCachedThreadPool().submit
(new Callable<Interger>()
{
int count = 1000;
#Override public Integer call() throws Exception
{
//here goes the operations you want to be executed concurrently.
return count + 1; //Or whatever the result is.
}
}
//Here goes the operations you need before the other thread is done.
System.out.println(future.get()); //Here you will retrieve the result from
//the other thread. if the result is not ready yet, the main thread
//(current thread) will wait for it to finish.
this way you don't have to deal with the synchronization problems and etc.
you can see further about this in Java documentations:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
When I put the code below in NetBeans, NetBeans gives me a warning next to it saying "Accessing static method sleep".
try {
Thread.currentThread().sleep(2000);
}
catch(InterruptedException ie){
//continue
}
Am I doing something wrong? Should I be calling this differently? I'm not doing anything multi-threaded. I just have a simple main method that which I want to sleep for a while.
Thread.currentThread() returns an instance of the Thread class. When invoking a static method you only want to work on the class itself. So invoking a static method on current thread you will get a warning you are calling the method on an instance.
You would just call Thread.sleep(2000); It would be equivalent to Thread.currentThread.sleep(2000);
This is important to know because people have been burned doing something like:
Thread a = new Thread(someRunnable);
a.start();
a.sleep(2000); //this will sleep the current thread NOT a.
Edit: So how do we sleep a? You sleep a by writing the sleep invocation within the runnable passed in to the constructor, like:
Runnable someRunnable = new Runnable(){
public void run(){
Thread.sleep(2000);
}
};
When 'a' is started, Thread.currentThread in someRunnable's run method is the 'a' thread instance.
sleep is static, so you access it with Thread.sleep(2000);. It affects the current thread.
From the javadoc:
Causes the currently executing thread
to sleep (temporarily cease execution)
for the specified number of
milliseconds. The thread does not lose
ownership of any monitors.
What that means is that you can't sleep another thread, only the one that the code is in.
Thats because the sleep() method is declared as static therefore
Thread.currentThread().sleep(2000);
is the same as
Thread.sleep(2000);
There is no method on Thread instances that corresponds to "sleep(long)".
Thread.currentThread().sleep(2000); does compile, however, because there is a method on the thread class that is called sleep() with a long argument.
Java allows this as a compiler time trick so that new coders could execute this when they are confused about the static access of methods.
However, what this actually is resolved to in the compiler is:
Thread.sleep(2000);
The following code is also equivalent:
Thread t = new Thread(new Runnable() { public void run() { // do nothing } });
t.sleep(2000);
As one poster (John V) has pointed out, this doesn't make the actual thread (t) instance sleep - the current thread that created the thread object is put to sleep.
The warning exists such that you remember that you're accessing a static method of a class, not a method of an instance variable.
The appropriate code to write is always Thread.sleep(2000); - never access static methods through an instance to avoid confusion and this warning.
netbeans giving you warning because you are accessing static method from Thread reference not from Thread class.
try this
try {
Thread.sleep(2000);
}
catch(InterruptedException ie){
//continue
}
sleep method Causes the currently executing thread to sleep.So no need to call Thread.currentThread().
Whenever you try to access static method using object it is not best practise, NB gives warning at that time, here is the same case
Thread.currentThread() will return you a object of Thread