synchronized block for an Integer object - java

I just came across the synchronized block in Java and wrote a small programm to test how it works.
I create 10 threads and let each thread increment an Integer object 1000 times.
So with synchronization I would assume a result of 10000 after all threads have finished their work and a result of less than 10000 without synchronization .
However the synchronization is not wokring as I expected.
I guess it has something to do with immutability of the object or so.
My program:
public class SyncTest extends Thread{
private static Integer syncObj = new Integer(0);
private static SyncTest[] threads = new SyncTest[10];
private boolean done = false;
public void run(){
for(int i = 0; i < 1000; i++){
synchronized(syncObj){
syncObj ++;
}
}
done = true;
}
public static void main(String[] args) {
for(int i=0; i < threads.length; i++){
threads[i] = new SyncTest();
threads[i].start();
}
while(!allDone()); //wait until all threads finished
System.out.println(syncObj);
}
private static boolean allDone(){
boolean done = true;
for(int i = 0; i < threads.length; i++){
done &= threads[i].done;
}
return done;
}
}
Can someone clarify this?

syncObject is changing each time you ++ it (the ++ is converting it to a primitive int, incrementing it, and then autoboxing it back to the Integer object. Integer objects are immutable ... once they are created, they cannot change.
Bottom ine is that you are not using the same syncPObj in all the threads, different threads use different syncObjects at different times to sync on.
use one object as the synchronization (call it syncObj), and declare it as a final Object:
private static final Object syncObject = new Object();
Then your counter should be a primitive (int) for perofrmance, call it 'counter' or something.
Synchronize on syncObject, and increment counter.
Edit: as per #jsn, the done flag is also broken in that your code has a 'tight loop' on the isAllDone() method, and that is bad practice. You should use thread[i].join() to wait (blocking) on each thread's completion, and then check the status from that. Using an ExecutorService is the 'right way'.

As assumed it is because of the immutability of the Integer object.
I've changed the synchonized block to
Integer old = syncObj;
syncObj ++;
System.out.println(syncObj == old);
and my console gets filled with falses
So each time I increment the Integer a new object is createt.
Therefore I only read from the old Object and it will not be locked.

These operations are usually done with Atomic. Have a look here. These structures are specifically designed for multi-threaded computation. Normal implementations are not thread safe.

Related

Why isn't synchronization taking place in this code?

package atask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Q3Synchronization
{
Integer sum=new Integer(0);
Q3Synchronization(){
ExecutorService e=Executors.newFixedThreadPool(1000);
for(int i=0;i<1000;i++){
e.execute(new Sum());
}
e.shutdown();
while(!e.isTerminated()){
}
System.out.println(sum);
}
public static void main(String[]args){
new Q3Synchronization();
}
class Sum implements Runnable{
#Override
public void run() {
m();
}
public synchronized void m(){
sum=sum+1;
}
}
}
The question is:
(Synchronize threads) Write a program that launches 1,000 threads. Each thread adds 1 to a variable sum that initially is 0. You need to pass sum by reference to each thread. In order to pass it by reference, define an Integer wrapper object to hold sum. Run the program with and without synchronization to see its effect.
In short
Object method synchronization/locking works on a per-instance basis.
Explanation
You are creating 1000 instances of the Sum class. Every call to m() is synchronized but does not cause any other thread to wait. This is because there are no concurrent calls to the same instance, rather there are calls to different instances. I attached your code with a minor change:
Sum s = new Sum();
for(int i=0;i<1000;i++){
e.execute(s);
}
If you try this change, you will always get a result of 1000 in your counter variable.
In the constructor you are creating new Sum() instance and passing it to separate thread. The method m() is obtaining lock (every thread when entering in syncronized block must acquire lock) on object. Therefore each thread can execute m() method concurrently which breaks your multhreading logic since (sum = sum + 1) is not atomic operation.
You can fix it either:
change sum variable to Atomic Integer and use addAndGet() to perform addition . E.g.
AtomicInteger sum= new AtomicInteger(0);
and method m to use atomic integer
public void m(){sum.addAndGet(1);}
2.Use the same object to acquire lock, so that method m will be syncronized properly. You can achieve it by creating one sum instance variable in your constructor like this .
final Sum sum = new Sum();
for (int i = 0; i < 1000; i++) {
`e.execute(sum);
}

Synchronization by object [duplicate]

I just came across the synchronized block in Java and wrote a small programm to test how it works.
I create 10 threads and let each thread increment an Integer object 1000 times.
So with synchronization I would assume a result of 10000 after all threads have finished their work and a result of less than 10000 without synchronization .
However the synchronization is not wokring as I expected.
I guess it has something to do with immutability of the object or so.
My program:
public class SyncTest extends Thread{
private static Integer syncObj = new Integer(0);
private static SyncTest[] threads = new SyncTest[10];
private boolean done = false;
public void run(){
for(int i = 0; i < 1000; i++){
synchronized(syncObj){
syncObj ++;
}
}
done = true;
}
public static void main(String[] args) {
for(int i=0; i < threads.length; i++){
threads[i] = new SyncTest();
threads[i].start();
}
while(!allDone()); //wait until all threads finished
System.out.println(syncObj);
}
private static boolean allDone(){
boolean done = true;
for(int i = 0; i < threads.length; i++){
done &= threads[i].done;
}
return done;
}
}
Can someone clarify this?
syncObject is changing each time you ++ it (the ++ is converting it to a primitive int, incrementing it, and then autoboxing it back to the Integer object. Integer objects are immutable ... once they are created, they cannot change.
Bottom ine is that you are not using the same syncPObj in all the threads, different threads use different syncObjects at different times to sync on.
use one object as the synchronization (call it syncObj), and declare it as a final Object:
private static final Object syncObject = new Object();
Then your counter should be a primitive (int) for perofrmance, call it 'counter' or something.
Synchronize on syncObject, and increment counter.
Edit: as per #jsn, the done flag is also broken in that your code has a 'tight loop' on the isAllDone() method, and that is bad practice. You should use thread[i].join() to wait (blocking) on each thread's completion, and then check the status from that. Using an ExecutorService is the 'right way'.
As assumed it is because of the immutability of the Integer object.
I've changed the synchonized block to
Integer old = syncObj;
syncObj ++;
System.out.println(syncObj == old);
and my console gets filled with falses
So each time I increment the Integer a new object is createt.
Therefore I only read from the old Object and it will not be locked.
These operations are usually done with Atomic. Have a look here. These structures are specifically designed for multi-threaded computation. Normal implementations are not thread safe.

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();
}

Implementing a cyclicbarrier in java using semaphores

The question is as follows, since the barrier is only called using down() so that it would wait for the n threads to arrive and then execute all n threads together in the critical region now how do I inform the threads calling on barrier.down that it can move on now. I tried adding notifyAll() after phase2() and that doesn't work. Help? :)
public class cyclicBarrier {
private int n;
private int count;
private semaphore mutex;
private semaphore turnstile;
private semaphore turnstile2;
public cyclicBarrier(int n){
this.n = n;
this.count = 0;
this.mutex = new semaphore(1);
this.turnstile = new semaphore(0);
this.turnstile2 = new semaphore(0);
}
public synchronized void down() throws InterruptedException{
this.phase1(); //waits for n threads to arrive
this.phase2(); //waits for n threads to execute
}
private synchronized void phase1() throws InterruptedException {
this.mutex.down();
this.count++;
if(this.count == this.n){
for(int i = 0; i < this.n; i++){
this.turnstile.signal(); //when n threads received then move on to phase 2
}
}
this.mutex.signal();
this.turnstile.down(); //keeps waiting till I get n threads
}
private synchronized void phase2() throws InterruptedException {
this.mutex.down();
this.count--;
if(this.count == 0){
for(int i = 0; i < this.n; i++){
this.turnstile2.signal(); //reset the barrier for reuse
}
}
this.mutex.signal();
this.turnstile2.down(); //keeps waiting till n threads get executed
}
}
public class semaphore {
private int counter;
public semaphore(int number){
if (number > 0) {
this.counter = number;
}
}
public synchronized void signal(){
this.counter++;
notifyAll();
}
public synchronized void down() throws InterruptedException{
while (this.counter <= 0){
wait();
}
this.counter--;
}
}
I see you're using the solution from The Little Book of Semaphores. One main point of the book is that you can solve many coordination problems using semaphores as the only coordination primitive. It is perfectly fine to use synchronized to implement a semaphore, since that is necessary to do it correctly. It misses the point, however, to use synchronized in the methods which solve a puzzle that is supposed to be solved with semaphores.
Also, I think it doesn't work in your case: don't you get a deadlock at this.turnstile.down()? You block on a semaphore which holding an exclusive lock (through synchronized) on the object and method which would allow that semaphore to get released.
Addressing the question as stated: you signal to threads that they can proceed by returning from barrier.down(). You ensure that you don't return too soon by doing turnstile.down().
Aside: Semaphore implementation
Your semaphore implementation looks correct, except that you only allow non-negative initial values, which is at least non-standard. Is there some motivation for doing this that I can't see? If you think negative initial values are wrong, why not throw an error instead of silently doing something else?
Aside: Other synchronization primitives
Note that the java constructs synchronized, .wait() and .notify() correspond to the Monitor coordination primitive. It may be instructive to solve the puzzles with monitors (or other coordination primitives) instead of semaphores, but I would recommend keeping those efforts separate. I've had a bit of fun trying to solve a puzzle using Haskell's Software Transactional Memory.
Aside: On runnability
You say you have tried things, which indicates that you have some code that allows you to run the code in the question. It would have been helpful if you had included that code, so we could easily run it too. I probably would have checked that my hypothesized deadlock actually occurs.

volatile keyword seems to be useless?

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.

Categories

Resources