Java -- sychronized Keyword

The "Lock" and "Condition" interface give programmers a high degree of control over locking. However, in most situations, you don't need that control -- you can use a mechanism that is built into the Java language. Ever since version 1.0, every object in Java has an intrinsic lock. IF a method is declared with the "synchronized" keyword, the object's lock protects the entire method ( not like "Lock" and "Condition" mechanism can protect a critical block). That is, to call the method, a thread must acquire the intrinsic object lock.

In other words,

public synchronized void method() {
    ... ...
    ... ...
}

is equivalent of 

public void method() {
    this.intrinsicLock.lock();

    try {
        ... ...
        ... ...
    } finally {
        this.intrinsicLoc.unlock();
    }

}

The "transfer" method of the simulated bank program can be refined like this: (I recommend readers to consider the comments within the following codes)

 public synchronized void transfer(int from, int to, double amount) {

        try {

            while (accounts[from] < amount) {
                notify();    //call this method to activate a waiting to be notified thread on this object. 
                             //It is equivalent to the call to "signal" method on a condition object.
                wait();      //this method make the current thread deactivated, give up the lock, waiting to be notified by others. 
                             //It is equivalent to the call to "await" method on a condition object.
            }

            System.out.print(Thread.currentThread());
            accounts[from] -= amount;
            System.out.printf(" %10.2f from %d to %d", amount, from, to);
            accounts[to] += amount;
            System.out.printf(" Total Balance: %10.2f\n", getTotalBalance());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            notifyAll();   //it is equivalent to the call to "signalAll" method on a condition object.
        } finally {
            notify();
        }

    }

The intrinsic locks and conditions have some limitations. Among them:

    You could not interrupt a thread that is trying to acquire a lock.

    You can not specify a timeout when trying to acquire a lock.

    Having a single condition per lock can be inefficient.

Synchronized Block:

There is a second mechanism for acquiring the lock: by entering a synchronized block. When a thread enters a block of the form:

synchronize (obj) {    //this is the syntax for a synchronized block
    critical section
}

then it acquire the lock for "obj" .

You will sometimes find "ad-hoc" locks, such as:

public class bank {
    private double[] accounts;
    private Object lock = new Object();
    ... ...
    ... ...
    public void transfer(int from, int to, double amount) {
        synchronized (lock) {    //an ad-hoc lock.
                                 //implicitly, every class extends the "Object" superclass, so that this syntax 
                                 //can obtain any object's intrinsic lock; in this case, 
                                 //can obtain the "accounts" 's intrinsic lock. In this way,
                                 //the atomic operation can be ensured.
            accounts[from] -= amount;
            accounts[to] += amount;
        }
        System.out.println(...);
    }
}



猜你喜欢

转载自blog.csdn.net/liangking81/article/details/80718044