|
|
|
Sponsored Link •
|
|
Advertisement
|
Synchronized blocks
In Java language terminology, the coordination of multiple threads that
must access shared data is called synchronization. The
language provides two built-in ways to synchronize access to data: with
synchronized statements or synchronized methods.
Synchronized statements
To create a synchronized statement, you use the
synchronized keyword with an expression that evaluates to
an object reference, as in the reverseOrder() method
below:
class KitchenSync {
private int[] intArray = new int[10];
void reverseOrder() {
synchronized (this) {
int halfWay = intArray.length / 2;
for (int i = 0; i < halfWay; ++i) {
int upperIndex = intArray.length - 1 - i;
int save = intArray[upperIndex];
intArray[upperIndex] = intArray[i];
intArray[i] = save;
}
}
}
}
In the case above, the statements contained within the synchronized
block will not be executed until a lock is acquired on the current
object (this). If instead of a this
reference, the expression yielded a reference to another object, the
lock associated with that object would be acquired before the thread
continued.
Two opcodes, monitorenter and monitorexit,
are used for synchronization blocks within methods, as shown in the
table below.
monitorenter |
pop objectref, acquire the lock associated with objectref | |
monitorexit |
pop objectref, release the lock associated with objectref |
When monitorenter is encountered by the Java virtual
machine, it acquires the lock for the object referred to by objectref
on the stack. If the thread already owns the lock for that object, a
count is incremented. Each time monitorexit is executed
for the thread on the object, the count is decremented. When the count
reaches zero, the monitor is released.
Here is the bytecode
sequence generated by the reverseOrder() method of the
KitchenSync class.
Note that a catch clause ensures the locked object will be unlocked even if an exception is thrown from within the synchronized block. No matter how the synchronized block is exited, the object lock acquired when the thread entered the block definitely will be released.
Synchronized methods
To synchronize an entire method, you just include the
synchronized keyword as one of the method qualifiers, as
in:
class HeatSync {
private int[] intArray = new int[10];
synchronized void reverseOrder() {
int halfWay = intArray.length / 2;
for (int i = 0; i < halfWay; ++i) {
int upperIndex = intArray.length - 1 - i;
int save = intArray[upperIndex];
intArray[upperIndex] = intArray[i];
intArray[i] = save;
}
}
}
The JVM does not use any special opcodes to invoke or return from synchronized methods. When the JVM resolves the symbolic reference to a method, it determines whether the method is synchronized. If it is, the JVM acquires a lock before invoking the method. For an instance method, the JVM acquires the lock associated with the object upon which the method is being invoked. For a class method, it acquires the lock associated with the class to which the method belongs. After a synchronized method completes, whether it completes by returning or by throwing an exception, the lock is released.
Next month
Now that I have gone through the entire bytecode instruction set, I
will be broadening the scope of this column to include various aspects
or applications of Java technology, not just the Java virtual machine.
Next month, I'll begin a multi-part series that gives an in-depth
overview of Java's security model.
About the author
Bill Venners has been writing software professionally for 12 years.
Based in Silicon Valley, he provides software consulting and training
services under the name Artima Software Company.
Over the years he has developed software for the consumer electronics,
education, semiconductor, and life insurance industries. He has
programmed in many languages on many platforms: assembly language
on various microprocessors, C on Unix, C++ on Windows, Java on the Web.
He is author of the book: Inside the Java Virtual Machine, published by McGraw-Hill.
You can reach him at bv@artima.com.
This article was first published under the name Under the Hood: How the Java virtual machine performs thread synchronization in JavaWorld, a division of Web Publishing, Inc., July 1997.
|
Sponsored Links
|