内置锁

xiaoxiao2021-03-01  12

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,服务的响应性非常低,无法令人接受。这是一个性能问题,而不是线程安全问题。

 

相关资源:Java 面经手册·小傅哥(公众号:bugstack虫洞栈).pdf
转载请注明原文地址: https://www.6miu.com/read-3100001.html

最新回复(0)