内置锁

Java 提供了一种内置锁机制来支持原子性:同步代码块。同步代码块包括两部分:一个作为锁的对象引用,一个作为由这个锁保护的代码块。以关键字synchronized来修饰的方法就是一种横跨整个方法体的同步代码块,其中 该同步代码块的锁就是方法调用所在的对象。静态的synchronized方法以Class对象作为锁。

synchronized(lock){
//访问或修改由锁保护的共享状态
}

 每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁(Intrisic Lock)或监视器锁(Monitor Lock)。线程在进入同步代码块之前会自动获得锁,并且在退出同步代码块时自动释放锁,而无论是通过正常的控制路径退出,还是通过从代码块中抛出异常退出。获得内置锁的唯一途径就是进入由这个锁保护的同步代码块或方法。

 Java内置锁相当于一种互斥锁,这意味着最多只有一个线程能持有这种锁。当线程A尝试获取一个由线程B持有的锁时,线程A必须等待或者组赛,知道线程B释放这个锁。如果B永远不释放锁,A将永远地等下去,就构成死锁。

 由于每次只能有一个线程执行内置锁保护的代码块,因此,由这个锁保护的同步代码块会以原子方式执行,多个线程在执行该代码块时也不会相互干扰。并发环境中的原子性与事物应用程序中的原子性有着相同的含义----一组语句作为一个不可分割的单元被执行。任何一个执行同步代码块的线程,都不可能看到有其他线程正在执行由同一个锁保护的同步代码块。

public class SynchronizedFactorizer implements Servlet{
    private BigInteger lastNumber;
    private BigInteger[] lastFactors;

    public syncronized void service(ServletRequest req,ServletResponse resp){
        BigInteget i=extractFromRequest(req);
        if(i.equals(lastNumber))
             encodeIntoResponse(resp,lastFactors);
        else{
             BigInteger[] factors=factor(i);
             lastNum=i;
            lastFactors=factors;
            encodeIntoResponse(resp,factors);
 
         }
 
  }
}

   我们在上面程序中使用了关键字synchronized来修饰service方法,因此在同一时刻只有一个线程可以执行service方法。然而,这种方法 过于极端,因为多个客户端无法同时使用因数分解servlet,服务的响应性非常低,无法令人接受。这是一个性能问题,而不是线程安全问题。

猜你喜欢

转载自dbp5588.iteye.com/blog/2368593