synchronized关键字

来源:互联网 发布:知乎用户数量一亿 编辑:程序博客网 时间:2024/06/05 11:31
  在前面一节中,介绍了如何使用Lock和Condition对象,在进一步深入之前,总结以下有关锁和条件的关键之处:
锁用来保护代码片段,任何时刻只能有一个线程被保护的代码
锁可以管理试图进入被保护代码段的线程
锁可以拥有一个或者多个相关的条件对象
每个条件对象管理那些已经进入倍保护代码但还不能运行的线程
Lock和Condition接口被添加到JAVA SE5.0中,这也向程序设计人员提供了高度的封锁控制。然而,大多数情况下,并不需要那样的控制,并且可以使用一种嵌入到JAVA语言内部的机制。从1.0开始,JAVA中的每一个对象都有哟哥内部锁。如果一个方法用synchronized关键字声明,那么对象的锁将保护整个方法,也就是说,要调用该方法,线程必须获得内部的对象锁。
换句话说,
public synchronized void method(){
    method body
}
等价与
public void methed(){
    this.intrinsicLock.lock();
    try
    {
        method body
    }
    finally{this.intrinsicLock.unlock();}
}
可以简单的声明类的某个方法为synchronized,而不是使用一个显式的锁。
内部对象锁只有一个相关条件。wait方法添加一个线程到等待集中,notifyAll/notify方法接触等待线程的阻塞状态。换句话说,d调用wait或者notifyAll等价于
intrinsicCondition.await();
intrinsicCondition.signalAll();
    wait,notifyAll以及notify方法是Object类的final方法。Condition方法必须被命名为await,signalAll和signal以便他们不会与那些方法发生冲突。
例如,可以用JAVA实现Bank类如下:
class Bank{
    public synchronized void transfer(int from,int to,int amounrt) throws InterruptedException{
        while(account[from]<amount)
            wait();
        account[from] -= amount;
        account[to] += amount;
        notifyAll();
    }
    public synchronized double getTotalBalance(){...}
    private double[] accounts;
}
可以看到,使用synchronized关键字来编写代码要简洁很多。当然,要理解这一代码,必须了解每一个对象有一个内部锁,并且该锁有一个内部条件。由锁来管理那些试图进入synchronized方法的线程,由条件来管理那些调用wait的线程。
将静态方法声明为synchronized也是合法的。如果调用这种方法,该方法获得相关的类的内部锁,例如,如果Bank类有一个静态同步的方法,那么当该方法调用时,Bank.class对象的锁被锁住。因此,没用其他线程可以调用同一个类的这个或者任何其他的同步静态方法。
内部锁和条件存在一些局限。包括:
不能中断一个正在试图获得锁的线程。
试图获得锁时不能设定超时。
每个锁仅有单一的条件,可能是不够的。
0 0