Synchronized


Semantically, you want all of the code in withdraw to execute atomically. A thread should be able to execute the entire withdraw method, start to finish, without any other thread interfering. You can accomplish this in Java through use of the synchronized method modifier.

 public synchronized void withdraw(BigDecimal amount) {    if (amount.compareTo(balance) > 0)       return;    balance = balance.subtract(amount); } 

This implementation of synchronization in Java is known as mutual exclusion. Another way you can refer to the code protected by mutual exclusion is as a critical section.[9] In order to ensure that the withdraw code executes mutually exclusively, Java places a lock on the object in which the thread's code is executing. While one thread has a lock on an object, no other thread can obtain a lock on that object. Other threads that try to do so will block until the lock is released. The lock is released when the method completes execution.

[9] [Sun2004].

Java uses a concept known as monitors to protect data. A monitor is associated with each object; this monitor protects the object's instance data. A monitor is associated with each class; it protects the class's static data. When you acquire a lock, you are acquiring the associated monitor; only one thread can acquire a lock at any given time.[10]

[10] http://www.artima.com/insidejvm/ed2/threadsynch2.html.

You should always try to lock the smallest amount of code possible, otherwise you may experience performance problems while other threads wait to obtain a lock. If you are creating small, composed methods as I've repetitively recommended, you will find that locking at the method level suffices for most needs. However, you can lock at a smaller atomicity than an entire method by creating a synchronized block. You must also specify an object to use as a monitor by enclosing its reference in parentheses after the synchronized keyword.

The following implementation of withdraw is equivalent to the above implementation.

 public void withdraw(BigDecimal amount) {    synchronized(this) {       if (amount.compareTo(balance) > 0)          return;       balance = balance.subtract(amount);    } } 

A synchronized block requires the use of braces, even if it contains only one statement.

You can declare a class method as synchronized. When the VM executes a class method, it will obtain a lock on the Class object for which the method is defined.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net