JAVA并发学习之基础概念

来源:互联网 发布:淘宝无线地址转换器 编辑:程序博客网 时间:2024/06/07 23:22

个人更多更新的博文,欢迎访问我的个人博客,欢迎留言一起学习 浅唱

关于java并发编程的相关文章都是阅读了《java并发编程实战》之后的读书笔记总结

  • 线程安全性

    当多个线程访问某个类时,这个类始终都能表现出正确的行为,即类的行为于其规范完全一致,则这个类是线程安全的。

  • 原子性

    对于一个操作,如果其行为是不可分割的(任意时刻,只有一个线程能够执行某一段代码),则称这样的操作是具有原子性的。

  • 可见性

    可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的,它要对付内存缓存和编译器优化的各种反常行为。

    线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程以读/写共享变量的副本。(本地内存是jmm的抽象概念)。示意图如下所示

    java内存模型抽象图

  • 重排序

    在执行程序时为了提高性能,编译器和处理器往往会对指令进行重排序,其中包括以下三种类型:

    • 编译器优化的重排序。编译器在不改变单线程程序语义的前提下,重排语句的执行顺序;
    • 指令级别的重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行,如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
    • 内存系统的重排序。由于处理器使用了缓存和读/写缓冲区,使得加载和存储操作看上去可能是乱序执行的

    关于这一块的内容可以参考 《深入理解java内存模型》 程晓明著

  • 重入

    当某个线程请求一个由其他线程所持有的锁时,发出的请求会阻塞。但如果某个线程试图获得一个已经由它自己所持有的锁,那么这个请求就会成功,因为内置锁(每个java对象都可以用作一个实现同步的锁,这些锁被称为内置锁)是可重入的。

  • 线程封闭

    当访问共享的可变对象的时候,通常要使用同步,一种避免使用同步的方式就是不共享数据。如果仅在单线程内访问数据,就不需要使用同步。这种技术就被称为线程封闭。

    • Ad-hoc线程封闭

      维护线程封闭性的职责完全由程序实现来承担。

    • 栈封闭

      在栈封闭中,只能通过局部变量才能访问对象。(使用局部栈封闭的时候,需要防止对象的溢出,即存在一个局部方法内部外的引用指向了局部方法内的对象)

    • ThreadLocal类

      ThreadLocal能使线程中的某个值域保存值的对象关联起来,通过提供get与set的接口,为每个使用该变量的线程都存有一份独立的副本。ThreadLocal通常用于防止对可变的单实例变量或全局变量进行共享。

  • 发布对象

    使对象能够在当前域之外的对象中使用。对于可变的对象必须通过安全的方式发布。要安全地发布一个对象,对象的引用以及对象的状态必须同时对其他线程可见。通过以下方式可以实现安全发布:

    • 在静态初始化函数中初始化一个对象的引用
    • 将对象的引用保存到volatile类型的域或者AtomicReference对象中
    • 将对象的引用保存到某个正确构造对象的final类型域中
    • 将对象的引用保存到一个由锁保护的域中
  • 总的来说,在并发程序中使用和共享变量时,可以使用以下的策略

    • 线程封闭。 线程封闭对象只能由一个线程拥有,对象被封闭在线程中,并且只能由该线程修改

    • 只读共享。 在没有额外的同步的情况下,共享的只读对象可以由多个线程并发访问,但任何线程都不修改它。

    • 线程安全共享。 线程安全的对象在其内部都实现同步,多个线程可以使用公有的接口进行访问不需要进一步的同步处理

    • 保护对象。 被保护的对象只能通过持有特定的锁来访问。

    下面附上一张知识的结构汇总图:

    0 0
    原创粉丝点击