Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 430
Kiyoshi Motoki Avatar asked Mar 13 '23 09:03

Kiyoshi Motoki


2 Answers

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.

like image 70
michele b Avatar answered Mar 25 '23 06:03

michele b


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.

like image 37
Troncador Avatar answered Mar 25 '23 05:03

Troncador