volatile keyword seems to be useless? - java

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main implements Runnable {
private final CountDownLatch cdl1 = new CountDownLatch(NUM_THREADS);
private volatile int bar = 0;
private AtomicInteger count = new AtomicInteger(0);
private static final int NUM_THREADS = 25;
public static void main(String[] args) {
Main main = new Main();
for(int i = 0; i < NUM_THREADS; i++)
new Thread(main).start();
}
public void run() {
int i = count.incrementAndGet();
cdl1.countDown();
try {
cdl1.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
bar = i;
if(bar != i)
System.out.println("Bar not equal to i");
else
System.out.println("Bar equal to i");
}
}
Each Thread enters the run method and acquires a unique, thread confined, int variable i by getting a value from the AtomicInteger called count. Each Thread then awaits the CountDownLatch called cdl1 (when the last Thread reaches the latch, all Threads are released). When the latch is released each thread attempts to assign their confined i value to the shared, volatile, int called bar.
I would expect every Thread except one to print out "Bar not equal to i", but every Thread prints "Bar equal to i". Eh, wtf does volatile actually do if not this?
It is a deliberate intention that each Thread attempts to set the value of bar at exactly the same time.
EDIT:
In light of the answer, changed code to this:
...
bar = i;
try {
Thread.sleep(0);
} catch(InterruptedException e) {
e.printStackTrace();
}
...
To ensure that a little time is wasted between the set and read of the variable.
Now the print is 50/50 on same/different value for Bar.

The JVM decides when the threads run, not you. If it felt like holding one of the ones whose latch just released for another 10ms, just because, it can do that. After the latch releases, they still have to wait for their turn to execute. Unless you're running it on a 25 core computer, they're not all assigning bar at anywhere near 'the same time' down inside the machine. Since all you're doing is a couple of primitive operations, it's extremely unlikely that one of them won't finish inside its time slice before the next one gets released!

It's not. You're misusing it. There is a great article here by Herb Sutter that explains it in more detail.
The basic idea is that volatile makes variables unoptimisable. It does not make them thread safe.

To answer the 'WTF does volatile actually do?':
volatile is all about visibility. In Java's thread model, if a thread A writes into a regular shared field, there is no guarantee that a thread B will ever see the value written by A, unless the threads are synchronized somehow. volatile is one of the synchronization mechanisms.
Unlike non-volatile fields, when thread A writes into a volatile field and thread B later reads it, B is guaranteed to see the new value and not an older version.
(Actually volatile does even more - thread B will not only see the new value of the field, but everything else written by A before it set the volatile variable as well. It established a happened-before relationship).

What you should do is replace your instance of volatile int with AtomicInteger. See here.

I think you meant to write this:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main implements Runnable {
private final CountDownLatch cdl1 = new CountDownLatch(NUM_THREADS);
private volatile int bar = 0;
private AtomicInteger count = new AtomicInteger(0);
private static final int NUM_THREADS = 25;
public static void main(String[] args) {
Main main = new Main();
for(int i = 0; i < NUM_THREADS; i++)
new Thread(main).start();
}
public void run() {
int i = count.incrementAndGet();
bar = i;
cdl1.countDown();
try {
cdl1.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(bar != i)
System.out.println("Bar not equal to i");
else
System.out.println("Bar equal to i");
}
}
Which prints "Bar not equal to i" like you expected.

Related

Is this synchronized block need?

Is the synchronized block on System.out.println(number); need the following code?
import java.util.concurrent.CountDownLatch;
public class Main {
private static final Object LOCK = new Object();
private static long number = 0L;
public static void main(String[] args) throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
Worker worker = new Worker(doneSignal);
worker.start();
}
doneSignal.await();
synchronized (LOCK) { // Is this synchronized block need?
System.out.println(number);
}
}
private static class Worker extends Thread {
private final CountDownLatch doneSignal;
private Worker(CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
#Override
public void run() {
synchronized (LOCK) {
number += 1;
}
doneSignal.countDown();
}
}
}
I think it's need because there is a possibility to read the cached value.
But some person say that:
It's unnecessary.
Because when the main thread reads the variable number, all of worker thread has done the write operation in memory of variable number.
doneSignal.await() is a blocking call, so your main() will only proceed when all your Worker threads have called doneSignal.countDown(), making it reach 0, which is what makes the await() method return.
There is no point adding that synchronized block before the System.out.println(), all your threads are already done at that point.
Consider using an AtomicInteger for number instead of synchronizing against a lock to call += 1.
It is not necessary:
CountDownLatch doneSignal = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
Worker worker = new Worker(doneSignal);
worker.start();
}
doneSignal.await();
// here the only thread running is the main thread
Just before dying each thread countDown the countDownLatch
#Override
public void run() {
synchronized (LOCK) {
number += 1;
}
doneSignal.countDown();
}
Only when the 10 thread finish their job the doneSignal.await(); line will be surpass.
It is not necessary because you are waiting for "done" signal. That flush memory in a way that all values from the waited thread become visible to main thread.
However you can test that easily, make inside the run method a computation that takes several (millions) steps and don't get optimized by the compiler, if you see a value different than from the final value that you expect then your final value was not already visible to main thread. Of course here the critical part is to make sure the computation doesn't get optimized so a simple "increment" is likely to get optimized. This in general is usefull to test concurrency where you are not sure if you have correct memory barriers so it may turn usefull to you later.
synchronized is not needed around System.out.println(number);, but not because the PrintWriter.println() implementations are internally synchronized or because by the time doneSignal.await() unblocks all the worker threads have finished.
synchronized is not needed because there's a happens-before edge between everything before each call to doneSignal.countDown and the completion of doneSignal.await(). This guarantees that you'll successfully see the correct value of number.
Needed
No.
However, as there is no (documented) guarantee that there will not be any interleaving it is possible to find log entries interleaved.
System.out.println("ABC");
System.out.println("123");
could print:
AB1
23C
Worthwhile
Almost certainly not. Most JVMs will implement println with a lock open JDK does.
Edge case
As suggested by #DimitarDimitrov, there is one further possible use for that lock and it is to ensure a memory barrier is crossed befor accessing number. If that is the concern then you do not need to lock, all you need to do is make number volatile.
private static volatile long number = 0L;

Are unsynchronized reads (combined with synchronized writes) eventually consistent

I have a use case with many writer threads and a single reader thread. The data being written is an event counter which is being read by a display thread.
The counter only ever increases and the display is intended for humans, so the exact point-in-time value is not critical. For this purpose, I would consider a solution to be correct as long as:
The value seen by the reader thread never decreases.
Reads are eventually consistent. After a certain amount of time without any writes, all reads will return the exact value.
Assuming writers are properly synchronized with each other, is it necessary to synchronize the reader thread with the writers in order to guarantee correctness, as defined above?
A simplified example. Would this be correct, as defined above?
public class Eventual {
private static class Counter {
private int count = 0;
private Lock writeLock = new ReentrantLock();
// Unsynchronized reads
public int getCount() {
return count;
}
// Synchronized writes
public void increment() {
writeLock.lock();
try {
count++;
} finally {
writeLock.unlock();
}
}
}
public static void main(String[] args) {
List<Thread> contentiousThreads = new ArrayList<>();
final Counter sharedCounter = new Counter();
// 5 synchronized writer threads
for(int i = 0; i < 5; ++i) {
contentiousThreads.add(new Thread(new Runnable(){
#Override
public void run() {
for(int i = 0; i < 20_000; ++i) {
sharedCounter.increment();
safeSleep(1);
}
}
}));
}
// 1 unsynchronized reader thread
contentiousThreads.add(new Thread(new Runnable(){
#Override
public void run() {
for(int i = 0; i < 30; ++i) {
// This value should:
// +Never decrease
// +Reach 100,000 if we are eventually consistent.
System.out.println("Count: " + sharedCounter.getCount());
safeSleep(1000);
}
}
}));
contentiousThreads.stream().forEach(t -> t.start());
// Just cleaning up...
// For the question, assume readers/writers run indefinitely
try {
for(Thread t : contentiousThreads) {
t.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void safeSleep(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
//Don't care about error handling for now.
}
}
}
There is no guarantee that the readers would ever see an update to the count. A simple fix is to make count volatile.
As noted in another answer, in your current example, the "Final Count" will be correct because the main thread is joining the writer threads (thus establishing a happens-before relationship). however, your reader thread is never guaranteed to see any update to the count.
JTahlborn is correct, +1 from me. I was rushing and misread the question, I was assuming wrongly that the reader thread was the main thread.
The main thread can display the final count correctly due to the happens-before relationship:
All actions in a thread happen-before any other thread successfully returns from a join on that thread.
Once the main thread has joined to all the writers then the counter's updated value is visible. However, there is no happens-before relationship forcing the reader's view to get updated, you are at the mercy of the JVM implementation. There is no promise in the JLS about values getting visible if enough time passes, it is left open to the implementation. The counter value could get cached and the reader could possibly not see any updates whatsoever.
Testing this on one platform gives no assurance of what other platforms will do, so don't think this is OK just because the test passes on your PC. How many of us develop on the same platform we deploy to?
Using volatile on the counter or using AtomicInteger would be good fixes. Using AtomicInteger would allow removing the locks from the writer thread. Using volatile without locking would be OK only in a case where there is just one writer, when two or more writers are present then ++ or += not being threadsafe will be an issue. Using an Atomic class is a better choice.
(Btw eating the InterruptedException isn't "safe", it just makes the thread unresponsive to interruption, which happens when your program asks the thread to finish early.)

Concurrent Thread-safe AtomicInteger

I've read through the API documentation of the java.util.concurrent package, but have obviously misunderstood something. The overview says
A small toolkit of classes that support lock-free thread-safe
programming on single variables.
However, a small test application shows that the AtomicInteger class does not provide thread-safety, at least when it is shared across threads (I accept that the getAndSet / increment methods themselves are at least atomic)
Test:
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntTest
{
public static void main(String[] args) throws InterruptedException
{
AtomicInteger atomicInt = new AtomicInteger(0);
WorkerThread w1 = new WorkerThread(atomicInt);
WorkerThread w2 = new WorkerThread(atomicInt);
w1.start();
w2.start();
w2.join(); // <-- As pointed out by StuartLC and BarrySW19, this should be w1.join(). This typo allows the program to produce variable results because it does not correctly wait for *both* threads to finish before outputting a result.
w2.join();
System.out.println("Final value: " + atomicInt.get());
}
public static class WorkerThread extends Thread
{
private AtomicInteger atomicInt = null;
private Random random = new Random();
public WorkerThread(AtomicInteger atomicInt)
{
this.atomicInt = atomicInt;
}
#Override
public void run()
{
for (int i = 0; i < 500; i++)
{
this.atomicInt.incrementAndGet();
try
{
Thread.sleep(this.random.nextInt(50));
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
When I run this class, I consistently get results ranging from around 950 to 1000, when I would expect to always see exactly 1000.
Can you explain why do I not get consistent results when two threads access this shared AtomicInteger variable? Have I misunderstood the thread-safety guarantee?
Looks like a simple cut&paste error - you are joining to thread "w2" twice and never to "w1". At present, you would expect the thread "w1" to still be running half the time when you print the 'final' value.

Multi-threading program to print numbers from 1 to 50?

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

Java volatile variable doesn't behave correctly.

public class MyThread
{
volatile static int i;
public static class myT extends Thread
{
public void run ()
{
int j = 0;
while(j<1000000){
i++;
j++;
}
}
}
public static void main (String[] argv)
throws InterruptedException{
i = 0;
Thread my1 = new myT();
Thread my2 = new myT();
my1.start();
my2.start();
my1.join();
my2.join();
System.out.println("i = "+i);
}
}
Since volatile builds happens-before relationship, the final value of i should be strictly 2000000. However, the actual result is nothing different from being without volatile for variable i. Can anyone explanation why it doesn't work here? Since i is declared volatile, it should be protected from memory inconsistency.
Can anyone explanation why it doesn't work here? Since i is declared volatile, it should be protected from memory inconsistency.
It is protected but unfortunately i++ is not an atomic operation. It is actually read/increment/store. So volatile is not going to save you from the race conditions between threads. You might get the following order of operations from your program:
thread #1 reads i, gets 10
right afterwards, thread #2 reads i, gets 10
thread #1 increments i to 11
thread #2 increments i to 11
thread #1 stores 11 to i
thread #2 stores 11 to i
As you can see, even though 2 increments have happened and the value has been properly synchronized between threads, the race condition means the value only went up by 1. See this nice looking explanation. Here's another good answer: Is a volatile int in Java thread-safe?
What you should be using are AtomicInteger which allows you to safely increment from multiple threads.
static final AtomicInteger i = new AtomicInteger(0);
...
for (int j = 0; j<1000000; j++) {
i.incrementAndGet();
}

Categories

Resources