内在锁和同步(Intrinsic Locks and Synchronization)

来源:互联网 发布:twisted python 编辑:程序博客网 时间:2024/05/22 16:18

   同步是建立在内在锁或者监控锁的内部实体上的(java API说明书通常将这个实体称为监视器)。内在锁在两个方面扮演重要角色,强制排除访问一个对象状态和对可见性关键建立发生现行关系。

   每个对象都有一个它相关的内在锁。按照惯例,一个需要独立和一致性访问一个对象属性的线程在访问它们之前获取这个对象内在锁并在完成时释放锁。当它们在获取这锁和释放这锁这段时间内独这个线程立占有这内在锁。只要一个线程拥有了一个对象的内在锁,那么其它线程在同一个时刻将没法再获得锁,当它们试图获取这锁时,将会发生阻塞。

   当一个线程释放了对象内在锁,在这个瞬间和下一个获取同一个锁的线程将会创建现行发生关系。

同步方法中的锁
   当一个线程调用同步方法,它自动获取方法对象的内在锁并在方法返回时释放这个锁,尽管在因为异常导致方法返回时,这锁也同样会被释放。

同步语句块
   另外一种是使用synchronized语句创建同步代码,和同步方法不同的是,同步语句必须指定提供内在锁的对象:

public void addName(String name){    synchronized(this){        lastName = name;        nameCount++;    }    nameList.add(name);} 

   这个例子中,addName方法需要同步修改lastName和nameCount,但是同样需要避免同步调用对象其它方法(在同步代码块中调用对线对象其它方法将会产出一些活跃性的问题)。没有同步语句,那么就需要分开nameList.add方法。

   同步语句在提高并发也是有用的。假设,类MsLunch有两个属性c1和c2,这两个属性不会一起被使用。所有属性的更新必须同步,但是不能阻止对c1更新的同时更新c2,否则,不必要的阻塞将会减少降低并发,使用this锁,代替同步方法,我们创建两个独立的对象来提供锁。

public class MsLunch{    private long c1 = 0;    private long c2 = 0;    private Object lock1 = new Object();    private Object lock2 = new Object();    public void inc1(){        synchronized(lock1){            c1++;        }    }    public void inc2(){        synchronized(lock2){            c2++;        }    }} 

要很小心的使用这种方法,你必须绝对保证交叉访问这些属性是安全的。

可重入同步
回想一下,一个线程不能获取另外一个线程占有的锁,但是一个线程可以获取一个它已经占有的锁。使一个线程获取一个相同的锁而不是让它重入同步,这描述了一个情景,一个同步代码块,直接或者间接的调用另一个包含同步代码块,并且这两个都是用一个锁。不用重入同步,同步代码块为了避免一个线程自己造成阻塞,必须要做额外的警惕。

0 0
原创粉丝点击