I've read that "volatile" in Java allows different threads to have access to the same field and see changes the other threads has made to that field. If that's the case, I'd predict that when the first and second thread have completely run, the value of "d" will be incremented to 4. But instead, each thread increments "d" to a value of 2.
public class VolatileExample extends Thread {
private int countDown = 2;
private volatile int d = 0;
public VolatileExample(String name) {
super(name);
start();
}
public String toString() {
return super.getName() + ": countDown " + countDown;
}
public void run() {
while(true) {
d = d + 1;
System.out.println(this + ". Value of d is " + d);
if(--countDown == 0) return;
}
}
public static void main(String[] args) {
new VolatileExample("first thread");
new VolatileExample("second thread");
}
}
The results from running this program are:
first thread: countDown 2. Value of d is 1
second thread: countDown 2. Value of d is 1
first thread: countDown 1. Value of d is 2
second thread: countDown 1. Value of d is 2
I understand that if I add keyword "static" the program,
(that is, "private static volatile int d = 0;"), "d" would be incremented to 4.
And I know that's because d will become a variable that the whole class shares rather than each instance getting a copy.
The results look like:
first thread: countDown 2. Value of d is 1
first thread: countDown 1. Value of d is 3
second thread: countDown 2. Value of d is 2
second thread: countDown 1. Value of d is 4
My question is, why doesn't "private volatile int d = 0; " yield similar results if volatile is supposed to allow the sharing of "d" between the two threads? That is, if the first thread updates the value of d to 1, then why doesn't the second thread grab the value of d as 1 rather than as zero?
volatile doesn't "allow the sharing" of anything. It just prevents the variable from being cached thread local, so that changes to the variables value occur immediately. Your d variable is an instance variable and is thus owned by the instance that holds it. You'll want to re-read the threading tutorials to re-align your assumptions.
One decent reference is here
There are a couple of misunderstandings here. You seem not to properly understand what a thread is, what an instance field is and what a static field is.
An instance field is a memory location that gets allocated once you instantiate a class (ie, a memory location gets allocated for a field d when you VolatileExample v = new VolatileExample()). To reference that memory location from within the class, you do this.d (then you can write to and read from that memory location). To reference that memory location from outside the class, it must be acessible (ie, not private), and then you'd do v.d. As you can see, each instance of a class gets its own memory location for its own field d. So, if you have 2 different instances of VolatileExample, each will have its own, independent, field d.
A static field is a memory location that gets allocated once a class is initialized (which, forgetting about the possibility of using multiple ClassLoaders, happens exactly once). So, you can think that a static field is some kind of global variable. To reference that memory location, you'd use VolatileExample.d (accessibility also applies (ie, if it is private, it can only be done from within the class)).
Finally, a thread of execution is a sequence of steps that will be executed by the JVM. You must not think of a thread as a class, or an instance of the class Thread, it will only get you confused. It is as simple as that: a sequence of steps.
The main sequence of steps is what is defined in the main(...) method. It is that sequence of steps that the JVM will start executing when you launch your program.
If you want to start a new thread of execution to run simultaneously (ie, you want a separate sequence of steps to be run concurrently), in Java you do so by creating an instance of the class Thread and calling its start() method.
Let's modify your code a little bit so that it is easier to understand what is happening:
public class VolatileExample extends Thread {
private int countDown = 2;
private volatile int d = 0;
public VolatileExample(String name) {
super(name);
}
public String toString() {
return super.getName() + ": countDown " + countDown;
}
public void run() {
while(true) {
d = d + 1;
System.out.println(this + ". Value of d is " + d);
if(--countDown == 0) return;
}
}
public static void main(String[] args) {
VolatileExample ve1 = new VolatileExample("first thread");
ve1.start();
VolatileExample ve2 = new VolatileExample("second thread");
ve2.start();
}
}
The line VolatileExample ve1 = new VolatileExample("first thread"); creates an instance of VolatileExample. This will allocate some memory locations: 4 bytes for countdown and 4 bytes for d. Then you start a new thread of execution: ve1.start();. This thread of execution will access (read from and write to) the memory locations described before in this paragraph.
The next line, VolatileExample ve2 = new VolatileExample("second thread"); creates another instance of VolatileExample, which will allocate 2 new memory locations: 4 bytes for ve2's countdown and 4 bytes for ve2's d. Then, you start a thread of execution, which will access THESE NEW memory locations, and not those described in the paragraph before this one.
Now, with or without volatile, you see that you have two different fields d : each thread operates on a different field. Therefore, it is unreasonable for you to expect that d would get incremented to 4, since there's no single d.
If you make d a static field, only then both threads would (supposedly) be operating on the same memory location. Only then volatile would come into play, since only then you'd be sharing a memory location between different threads.
If you make a field volatile, you are guaranteed that writes go straight to the main memory and reads come straight from the main memory (ie, they won't get cached on some -- extremely fast -- processor-local cache, the operations would take longer but would be guaranteed to be visible to other threads).
It wouldn't, however, guarantee that you'd see the value 4 stored on d. That's because volatile solves visibility problem, but not atomicity problems: increment = read from main memory + operation on the value + write to main memory. As you can see, 2 different threads could read the initial value (0), operate (locally) on it (obtaining 1), then writing it to the main memory (both would end up writing 1) -- the 2 increments would be perceived as only 1.
To solve this, you must make the increment an atomic operation. To do so, you'd need to either use a synchronization mechanism -- a mutex (synchronized (...) { ... }, or an explicit lock) -- or a class designed specifically for this things: AtomicInteger.
volatile can make sharing safe (if atomicity of a single read or write operation is sufficient), it doesn't cause sharing.
Note that if you make d static, it is actually unspecified what value d would have, because the statement d = d + 1 is not atomic, i.e. a thread may be interrupted between reading and writing d. A synchronized block, or an AtomicInteger are the typical solutions for that.
Related
I have two threads to sell tickets.
public class MyThread {
public static void main(String[] args) {
Ticket ticket = new Ticket();
Thread thread1 = new Thread(()->{
for (int i = 0; i < 30; i++) {
ticket.sell();
} }, "A");
thread1.start();
Thread thread2 = new Thread(()->{
for (int i = 0; i < 30; i++) {
ticket.sell();
} }, "B");
thread2.start();
}
}
class Ticket {
private Integer num = 20 ;
private Object obj = new Object();
public void sell() {
// why shouldn't I use "num" as a monitor object ?
// I thought "num" is unique among two threads.
synchronized ( num ) {
if (this.num >= 0) {
System.out.println(Thread.currentThread().getName() + " sells " + this.num + "th ticket");
this.num--;
}
}
}
}
The output will be wrong if I use num as a monitor object.
But if I use obj as a monitor object, the output will be correct.
What's the difference between using num and using obj ?
===============================================
And why does it still not work if I use (Object)num as a monitor object ?
class Ticket {
private int num = 20 ;
private Object obj = new Object();
public void sell() {
// Can I use (Object)num as a monitor object ?
synchronized ( (Object)num ) {
if (this.num >= 0) {
System.out.println(Thread.currentThread().getName() + " sells " + this.num + "th ticket");
this.num--;
}
}
}
}
Integer is a boxed value. It contains a primitive int, and the compiler deals with autoboxing/autounboxing that int. Because of this, the statement this.num-- is actually:
num=Integer.valueOf(num.intValue()-1)
That is, the num instance containing the lock is lost once you perform that update.
The fundamental problem here is synchronizing on a non-final value.
The most important thing to understand about the Java Memory Model - that is, what values a thread sees whilst executing a Java program - is the happens-before relationship.
In the specific case of a synchronized block, actions done in one thread before exiting the synchronized block happen before actions done inside the synchronized block in another thread - so, if the first thread increments a variable inside that synchronized block, the second thread sees that updated value.
This goes over and above the well-known fact that a synchronized block can only be entered by one thread at a time: only one thread at a time and you get to see what the previous thread did.
// Thread 1 // Thread 2
synchronized (monitor) {
num = 1
} // Exiting monitor
// *happens before*
// entering monitor
synchronized (monitor) {
int n = num; // Guaranteed to see n = 1 (provided no other thread has entered a block synchronized on monitor and changed it first).
}
There is a very important caveat to this guarantee: it only holds if the two executions of the synchronized block use the same monitor. And that's not the same variable, it's the same actual concrete object on the heap (variables don't have monitors, they're just pointers to a value in the heap).
So, if you reassign the monitor inside the synchronized block:
synchronized (num) {
if (num > 0) {
num--; // This is the same as `num = Integer.valueOf(num.intValue() - 1);`
}
}
then you are destroying the happens-before guarantee, because the next thread to arrive at that synchronized block is entering the monitor of a different object (*).
Once you do, the behavior of your program is ill-defined: if you're lucky, it fails in an obvious way; if you're very unlucky, it can seem to work, and then start failing mysteriously at a later date.
Your code is just broken.
This isn't something that's specific to Integers either: this code would have the same problem.
// Assume `Object someObject = new Object();` is defined as a field.
synchronized (someObject) {
someObject = new Object();
}
(*) Actually, you still get a happens-before relationship for the new object: it's just not for the things inside this synchronized block, it's for things that happened in some other synchronized block that used the object as the monitor. Essentially, it's impossible to reason about what this means, so you may as well just consider it "broken".
The correct way to do it is to synchronize on a field that you can't (not just don't) reassign. You could simply synchronize on this (which can't be reassigned):
synchronized (this) {
if (num > 0) {
num--; // This is the same as `num = Integer.valueOf(num.intValue() - 1);`
}
}
Now it doesn't matter that you're reassigning num inside the block, because you're not synchronizing on it any more. You get the happens-before guarantee from the fact that you're always synchronizing on the same thing.
Note, however, that you must always access num from inside a synchronized block - for example, if you have a getter to get the number of tickets remaining, that must also synchronize on this, in order to get the happens-before guarantee that the value changed in the sell() method is visible in that getter.
This works, but it may not be entirely desirable: anybody who has access to a reference to your Ticket instance can also synchronize on it. This means they can potentially deadlock your code.
Instead, it is a common practice to introduce a private field which is used purely for locking: this is what the obj field gives you. The only modification from your code should be to make it final (and give it a better name than obj):
private final Object obj = new Object();
This can't be accessed outside your class, so nefarious clients cannot cause a deadlock for you directly.
Again, this can't be reassigned inside your synchronized block (or anywhere else), so there is no risk of you breaking the happens-before guarantee by reassigning it.
I am writing some code where
class A {
Integer x;
String y
}
I created an object of A and I am passing it to 2 runnable threads. First thread updates value x, while second one updates value y.
Is there any scenario where this can break? I mean, can there be a race condition if there are two threads updating different variables of the same object?
No, it will work fine. As long as any given variable is only updated by one thread (With some conditions on the reading of that variable by other threads) you will be okay.
It may not be the most comprehendible design depending on what you are doing--Also, as I alluded to above, don't count on reading those variables from another thread reliably, if you want that look into atomic objects or volatile. (Atomic will be quicker for writes from multiple threads, volatile may still be better if you are just writing from one thread and reading from others)
Multithreading is not only about race conditions it's also about memory visibility formulated by
jsr-133 which you absolutely have to learn if you want to understand concurrency in java.
There are probably many ways in which your code can break, one obvious example is if you create your object in Thread A change x in thread B and y in thread C you might never see those changes in Thread A.
Some code to illustrate:
A a = new A();
a.x = 0;
Thread t1 = new Thread( () -> {
while (true) {
a.x = 1;
}
});
Thread t2 = new Thread( () -> {
a.y = "a";
});
t1.start();
t2.start();
while(a.x == 0) {
}
System.out.println("might never get here");
One possible fix is to make x and y volatile
class A {
volatile Integer x;
volatile String y;
}
This will ensure that all threads see changes to x and y but you still need to make sure that the instance of A is safely published.
I was trying impact of thread priority and when println in run method stays in comment both threads end in the same time and I don't understand this behavior, can you explain ? Thank you.
Main.class
public class Main {
public static void main(String[] args) {
Test t1 = new Test("Thread #1");
Test t2 = new Test("Thread #2");
t1.thread.setPriority(10);
t2.thread.setPriority(1);
t1.thread.start();
t2.thread.start();
try {
t1.thread.join();
t2.thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t1.thread.getName() + ": " + t1.count);
System.out.println(t2.thread.getName() + ": " + t2.count);
System.out.println("End of main thread.");
}
}
Test.class
public class Test implements Runnable{
public Thread thread;
static boolean stop = false;
int count = 0;
public Test(String name){
thread = new Thread(this, name);
}
#Override
public void run(){
for(int i = 0; i < 10000000 && stop == false; i++){
count = i;
//System.out.println(count + " " + thread.getName());
}
stop = true;
System.out.println("End of " + thread.getName());
}
}
without println with println
End of Thread #1 End of Thread #1
End of Thread #2 End of Thread #2
Thread #1: 9999999 Thread #1: 9999999
Thread #2: 9999999 Thread #2: 3265646
End of main thread. End of main thread.
Your two threads access a shared mutable variable without proper synchronization. In this case, there is no guaranty about when (or whether at all) a thread will learn about a change made by another thread. In your case, the change made by one thread is not noticed by the other at all. Note that while for a primitive data type like boolean, not reading the up to date value is the worst thing that can happen, for non-primitive data types, even worse problems, i.e. inconsistent results could occur.
Inserting a print statement has the side effect of synchronizing the threads, because the PrintStream perform an internal synchronization. Since there is no guaranty that System.out will contain such a synchronizing print stream implementation, this is an implementation specific side-effect.
If you change the declaration of stop to
static volatile boolean stop = false;
the threads will re-read the value from the shared heap in each iteration, reacting immediately on the change, at the cost of reduced overall performance.
Note that there are still no guarantees that this code works as you expect, as there is no guaranty about neither, that the thread priority has any effect nor that threads run in parallel at all. Thread scheduling is implementation and environment dependent behavior. E.g. you might find out that not the thread with the highest priority finishes its loop first, but just the thread that happened to be started first.
To clarify: the only purpose of thread/process "priority," in any language environment on any operating system, is to suggest to the OS "which of these two 'ought to be, I think, run first'," if both of them happen to be instantaneously "runnable" and a choice must be made to run only one of them.
(In my experience, the best example of this in-practice is the Unix/Linux nice command, which voluntarily reduces the execution-priority of a command by a noticeable amount.) CPU-intensive workloads which perform little I/O can actually benefit from being given a reduced priority.
As other answerers have already stressed, it is impossible to predict "what will actually happen," and priority can never be used to alter this premise. You must explicitly use appropriate synchronization-primitives to assure that your code executes properly in all situations.
im trying to write a program in which two threads are created and the output should be like 1st thread prints 1 and the next thread prints 2 ,1st thread again prints 3 and so on. im a beginner so pls help me clearly. i thought thread share the same memory so they will share the i variable and print accordingly. but in output i get like thread1: 1, thread2 : 1, thread1: 2, thread2 : 2 nd so on. pls help. here is my code
class me extends Thread
{
public int name,i;
public void run()
{
for(i=1;i<=50;i++)
{
System.out.println("Thread" + name + " : " + i);
try
{
sleep(1000);
}
catch(Exception e)
{
System.out.println("some problem");
}
}
}
}
public class he
{
public static void main(String[] args)
{
me a=new me();
me b=new me();
a.name=1;
b.name=2;
a.start();
b.start();
}
}
First off you should read this http://www.oracle.com/technetwork/java/codeconventions-135099.html.
Secondly the class member variables are not shared memory. You need to explicitly pass an object (such as the counter) to both objects, such that it becomes shared. However, this will still not be enough. The shared memory can be cached by the threads so you will have race-conditions. To solve this you will need to use a Lock or use an AtomicInteger
It seems what you want to do is:
Write all numbers from 1 to 50 to System.out
without any number being printed multiple times
with the numbers being printed in order
Have this execution be done by two concurrent threads
First, let's look at what is happening in your code: Each number is printed twice. The reason for this is that i is an instance variable of me, your Thread. So each Thread has its own i, i.e., they do not share the value.
To make the two threads share the same value, we need to pass the same value when constructing me. Now, doing so with the primitive int won't help us much, because by passing an int we are not passing a reference, hence the two threads will still work on independent memory locations.
Let us define a new class, Value which holds the integer for us: (Edit: The same could also be achieved by passing an array int[], which also holds the reference to the memory location of its content)
class Value{
int i = 1;
}
Now, main can instantiate one object of type Value and pass the reference to it to both threads. This way, they can access the same memory location.
class Me extends Thread {
final Value v;
public Me(Value v){
this.v = v;
}
public void run(){
for(; v.i < 50; v.i++){
// ...
}
public static void main(){
Value valueInstance = new Value();
Me a = new Me(valueInstance);
Me b = new Me(valueInstance);
}
}
Now i isn't printed twice each time. However, you'll notice that the behavior is still not as desired. This is because the operations are interleaved: a may read i, let's say, the value is 5. Next, b increments the value of i, and stores the new value. i is now 6. However, a did still read the old value, 5, and will print 5 again, even though b just printed 5.
To solve this, we must lock the instance v, i.e., the object of type Value. Java provides the keyword synchronized, which will hold a lock during the execution of all code inside the synchronized block. However, if you simply put synchronize in your method, you still won't get what you desire. Assuming you write:
public void run(){ synchronized(v) {
for(; v.i < 50; v.i++) {
// ...
}}
Your first thread will acquire the lock, but never release it until the entire loop has been executed (which is when i has the value 50). Hence, you must release the lock somehow when it is safe to do so. Well... the only code in your run method that does not depend on i (and hence does not need to be locking) is sleep, which luckily also is where the thread spends the most time in.
Since everything is in the loop body, a simple synchronized block won't do. We can use Semaphore to acquire a lock. So, we create a Semaphore instance in the main method, and, similar to v, pass it to both threads. We can then acquire and release the lock on the Semaphore to let both threads have the chance to get the resource, while guaranteeing safety.
Here's the code that will do the trick:
public class Me extends Thread {
public int name;
final Value v;
final Semaphore lock;
public Me(Value v, Semaphore lock) {
this.v = v;
this.lock = lock;
}
public void run() {
try {
lock.acquire();
while (v.i <= 50) {
System.out.println("Thread" + name + " : " + v.i);
v.i++;
lock.release();
sleep(100);
lock.acquire();
}
lock.release();
} catch (Exception e) {
System.out.println("some problem");
}
}
public static void main(String[] args) {
Value v = new Value();
Semaphore lock = new Semaphore(1);
Me a = new Me(v, lock);
Me b = new Me(v, lock);
a.name = 1;
b.name = 2;
a.start();
b.start();
}
static class Value {
int i = 1;
}
}
Note: Since we are acquiring the lock at the end of the loop, we must also release it after the loop, or the resource will never be freed. Also, I changed the for-loop to a while loop, because we need to update i before releasing the lock for the first time, or the other thread can again read the same value.
Check the below link for the solution. Using multiple threads we can print the numbers in ascending order
http://cooltekhie.blogspot.in/2017/06/#987628206008590221
I'm doing a college class on Java concurrency and was recently given a simple task to create 5 threads numbered from 1 to 5, then get each thread to write its thread number to a static variable in the class using a synchronized static method.
The solution I was given by the lecturer is below:
public class thread1 extends Thread {
private int threadNumber;
private static int threadCount = 0;
private static int value;
public thread1(){
threadNumber = ++threadCount;
System.out.println("Thread " + threadNumber + " is created" );
}
public synchronized static void setValue(int v){
value = v;
try{
Thread.currentThread().sleep(100);
}
catch(InterruptedException e ){}
System.out.println("the current value of the variable is " + value);
}
public void run() {
setValue(threadNumber);
return;
}
public static void main(String[] args) {
for(int i = 0; i < 5; i++){
thread1 thr = new thread1();
thr.start();
}
}
}
The output is supposed to be as follows:
Thread 1 is created Thread 2 is created Thread 3 is
created Thread 4 is created Thread 5 is created the
current value of the variable is 1 the current value of the
variable is 2 the current value of the variable is 3 the
current value of the variable is 4 the current value of the
variable is 5
But the output I am getting is below:
Thread 1 is created Thread
2 is created Thread 3 is created Thread 4 is created
Thread 5 is created the current value of the variable is 1
the current value of the variable is 5 the current value of the
variable is 4 the current value of the variable is 3 the
current value of the variable is 2
The order of current value is obviously different each time.
Is the solution I've been given incorrect? It's obviously not working in fulfilling its intended purpose which is to print out each of the thread's value variables in order.
Could anyone shed some light on how I'd get it to print the thread numbers in order from 1 to 5 each time reliably? I thought the use of the synchronized setValue method would do the trick, but obviously not.
The Solution provided by your lecturer is absolutely correct.
You are not getting the intended order because 5 different Threads are created and each of them have to access the same method which is Synchronized.
When a method is Synchronized only One Object at a time can access it
In your case Only One Thread can access the setValue method,
when one Thread enters the method it acquires the lock and
the other threads wait for the lock ,when this Thread releases the lock ,
any waiting Thread can acquire it and execute the setValue method.
You can never guarantee in which order Threads will execute the method,
so you will get some different order of Threads on running this program eachtime
There is no guarantee that threads will execute in the order you call start method on them.
A synchronized block only means that two threads cannot access it simultaneously. The order of the thread to run is determined by scheduler.
The order in which the thread enters the monitor is not defined. Once a thread finishes execution inside the monitor any other thread waiting on that monitor can gain control of the critical section.