Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java critical sections, what should I synchronize on?

In Java, the idiomatic way to declare critical sections in the code is the following:

private void doSomething() {   // thread-safe code   synchronized(this) {     // thread-unsafe code   }   // thread-safe code } 

Almost all blocks synchronize on this, but is there a particular reason for this? Are there other possibilities? Are there any best practices on what object to synchronize on? (such as private instances of Object?)

like image 709
lindelof Avatar asked Jan 06 '09 11:01

lindelof


People also ask

Is it better to make whole method synchronized or only critical section synchronized?

To acquire a lock on an object for a specific set of code block, synchronized blocks are the best fit. As a block is sufficient, using a synchronized method will be a waste. More specifically with Synchronized Block , it is possible to define the object reference on which are want to acquire a lock.

What is the critical section and how can we achieve synchronization in threads?

Critical Section: When more than one processes access the same code segment that segment is known as the critical section. The critical section contains shared variables or resources which are needed to be synchronized to maintain the consistency of data variables.

How do you define a critical section in Java?

A critical section is a block of code that accesses a shared resource and can't be executed by more than one thread at the same time. To help programmers implement critical sections, Java (and almost all programming languages) offers synchronization mechanisms.

What does synchronize keyword do in Java?

The synchronized keyword prevents concurrent access to a block of code or object by multiple threads. All the methods of Hashtable are synchronized , so only one thread can execute any of them at a time.


2 Answers

As earlier answerers have noted, it is best practice to synchronize on an object of limited scope (in other words, pick the most restrictive scope you can get away with, and use that.) In particular, synchronizing on this is a bad idea, unless you intend to allow the users of your class to gain the lock.

A particularly ugly case arises, though, if you choose to synchronize on a java.lang.String. Strings can be (and in practice almost always are) interned. That means that each string of equal content - in the ENTIRE JVM - turns out to be the same string behind the scenes. That means that if you synchronize on any String, another (completely disparate) code section that also locks on a String with the same content, will actually lock your code as well.

I was once troubleshooting a deadlock in a production system and (very painfully) tracked the deadlock to two completely disparate open source packages that each synchronized on an instance of String whose contents were both "LOCK".

like image 122
Jared Avatar answered Oct 01 '22 17:10

Jared


First, note that the following code snippets are identical.

public void foo() {     synchronized (this) {         // do something thread-safe     } } 

and:

public synchronized void foo() {     // do something thread-safe } 

do exactly the same thing. No preference for either one of them except for code readability and style.

When you do synchronize methods or blocks of code, it's important to know why you are doing such a thing, and what object exactly you are locking, and for what purpose.

Also note that there are situations in which you will want to client-side synchronize blocks of code in which the monitor you are asking for (i.e. the synchronized object) is not necessarily this, like in this example :

Vector v = getSomeGlobalVector(); synchronized (v) {     // some thread-safe operation on the vector } 

I suggest you get more knowledge about concurrent programming, it will serve you a great deal once you know exactly what's happening behind the scenes. You should check out Concurrent Programming in Java, a great book on the subject. If you want a quick dive-in to the subject, check out Java Concurrency @ Sun

like image 42
Yuval Adam Avatar answered Oct 01 '22 15:10

Yuval Adam