0

This is similar to my previous question as I am still unclear with synchronized keyword.

This time I'll make it very short .

private int count = 0;

synchronized void increment() {
    count++;
}

count is an instance variable which is shared among 2 threads.

If Thread t1 and t2 tries to increment count and OS gives t1 a chance to increment count first :-

t1 takes the lock and atomically increments count, time taken to increment count is 1 min(consider) including time taken to get the lock .

But what about thread t2, It is has to wait until lock is released. After release of lock, t2 now increments count atomically which also takes 1 min .

So synchronization gives correctness but it also takes time to perform.Threads are meant for doing work in less amount of time so why to use synchronization in threads what's the use of it.

Is my understanding correct ?

Javed Solkar
  • 162
  • 11
  • You have fixed Atomicity but not visibility `count` should be `volatile` – Nitin Dandriyal May 11 '15 at 07:24
  • 1
    Its like you can use more people to finish some work in shorter time, but there are few tasks that only person can do at a given time(synchronization fixes that read about critical sections). – Nitin Dandriyal May 11 '15 at 07:28
  • 2
    @NitinDandriyal you may be thinking of other languages. According to the JVM spec, an action in a thread that has a happens-before relation with another thread is visible in that other thread. And synchronizing on the same monitor creates this happens-before relationship. Accessing the same volatile variable also does. – Erwin Bolwidt May 11 '15 at 07:30
  • @ErwinBolwidt Thanks for correcting me, true that on entry to and exit from `synchronized` on a particular object monitor, the entering/exiting thread also synchronizes copies of all variables with main memory. I had multiple CPU Thread execution units in mind while suggesting, I take that back – Nitin Dandriyal May 11 '15 at 07:42
  • @NitinDandriyal Ideally, count should be an `AtomicInteger`. – Chetan Kinger May 11 '15 at 07:53
  • @ChetanKinger May be `LongAdder` https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/LongAdder.html With Java8 – Nitin Dandriyal May 11 '15 at 08:20

4 Answers4

2

Yes, there is performance penalty in using synchronization. Concurrency here is to guarantee the integrity of shared variable read and write. In your case, without synchronization, t1 and t2 may read count with the same values (says 1), so when both threads exit the values of count is 2 even though you should expect it to be 3 (because it is increased twice)

Tony Vu
  • 4,251
  • 3
  • 31
  • 38
1

Not every thread must do a synchronized job (otherwise we lose the point of using threads).

An efficient scenario is where threads do independent jobs (e.g. draw graphical elements on one thread while playing a background music on another)

giorashc
  • 13,691
  • 3
  • 35
  • 71
1

A fast program is useless if it's incorrect.

Suppose your class is the one handling deposits of money on your account.

Suppose three of your customers ask the bank to deposit 1000 dollars to your account. And suppose the bank doesn't synchronize the deposit operation.

Since it's not synchronized, you might have a race condition:

  • all three customers read the current balance of your account in parallel: 0
  • all three customers increment it: so the account balance becomes $1000

The result: instead of having $3000 on your account, you only have $1000. But that went 2 milliseconds faster than with synchronization.

Do you prefer that situation, or would you prefer the operation to take 2 additional milliseconds, but have $3000 on your account?

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
0

To add to @Bathsheba's answer, in a situation where multiple Threads are sharing and accessing the same resource which is not an atomic variable, you need to ensure that only one Thread accesses the resource at a given time. Consider modifying your example above to the following:

private int count = 0;

synchronized void increment() {
    count = count + 1;
}

If you don't make the increment() method synchronized, then you run the risk of the count variable having an inconsistent state. Specifically, your two Threads could interleave (meaning they are both running at the time) and an increment operation by one Thread could be overwritten by another Thread.

Read here for more about synchronization: https://docs.oracle.com/javase/tutorial/essential/concurrency/interfere.html

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360