zoukankan      html  css  js  c++  java
  • 读书笔记-----Java并发编程实战(一)线程安全性

    线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施

    示例:一个无状态的Servlet

    1 @ThreadSafe
    2 public class StatelessFactorizer implements Servlet{
    3         public void service(ServletRequest req,ServletResponse resp){
    4             BigInteger i = extractFromRequest(req);
    5             BigInteger[] factors = factor(i);
    6             encodeIntoResponse(resp,factors);
    7         }
    8 }

    这个类是无状态的,因为它既不包含任何域,也不包含任何对其他类中域的引用,计算过程中用到的变量是局部变量没有被共享。

    无状态对象一定是线程安全的。

    在并发编程中,由于不恰当执行时序而出现不正确结果的情况,称为竞态条件。

    最常见的竞态类型就是先检查后执行操作:比如单例中的延迟初始化。

    像递增,递减操作看上去只有一个操作,但这个操作并非原子的,会导致结果变得不可靠。这种情况称为:读取-修改-写入的复合操作,也是竞态类型的一种。

    对于这些竞态条件类型的操作可以加上同步锁,或者使用一个现有的线程安全类。

    如:

     1  @ThreadSafe
     2  public class CountingFactorizer implements Servlet{
     3          private final AtomicLong count = new AtomicLong(0);
     4          public long getCount(){return count.get();}
     5          public void service(ServletRequest req,ServletResponse resp){
     6              BigInteger i = extractFromRequest(req);
     7              BigInteger[] factors = factor(i);
     8              count.incrementAndGet();
     9              encodeIntoResponse(resp,factors);
    10          }
    11  }

    在java.util.concurrent.atomic包中包含了一些原子变量类,用于实现在数值和对象引用上的原子状态转换。

    注意:当在不变性条件中涉及多个变量时,各个变量间并不是彼此独立的,而是某个变量的值会对其他变量的值产生约束。因此,当更新某一个变量时,需要在同一个原

    子操作中对其他变量同时更新

    重入:当某个线程请求一个由其他线程持有的锁时,发出的请求线程会被阻塞。然而内置锁是可以重入的,因此某个线程试图获得一个已经由他自己持有的锁,那么这个请求就会成

    功。

    这个过程可以描述为:线程请求一个未被持有的锁,JVM记下这个新的锁持有者,计数值置为1,当这个线程再次获取这个锁,计数值将递增。当线程退出同步代码块时,计数器会相

    应的递减。当计数值为0时,这个锁将被释放。

    示例:

     1 public class Widget{
     2      public synchronized void doSomething(){
     3              ...
     4       }
     5 }
     6 
     7 public class LoggingWidget extends Widget{
     8       public synchronized void doSomething(){
     9                  super.doSomething();
    10       }
    11 }

    使用锁保护时,对于包含多个变量的不变性条件,其中涉及的所有变量都需要由同一个锁来保护。

    注意:当执行时间较长的计算或者无法快速完成的操作时,一定不要持有锁。

  • 相关阅读:
    [Python3网络爬虫开发实战] 1.2.6-aiohttp的安装
    [Python3网络爬虫开发实战] 1.3.1-lxml的安装
    [Python3网络爬虫开发实战] 1.2.5-PhantomJS的安装
    [Python3网络爬虫开发实战] 1.2.3-ChromeDriver的安装
    [Python3网络爬虫开发实战] 1.2.4-GeckoDriver的安装
    [Python3网络爬虫开发实战] 1.2.2-Selenium的安装
    [Python3网络爬虫开发实战] 1.2.1-Requests的安装
    tensorflow 根据节点名称获取节点
    tensorflow 根据节点获取节点前的整张图
    tf.estimator.Estimator
  • 原文地址:https://www.cnblogs.com/krislight1105/p/3886786.html
Copyright © 2011-2022 走看看