java 并发编程

  1. 并发原理
    1. 并发与并行
    2. Java 内存模型
    3. 并发问题
  2. 并发工具
  3. 并发编程建议

并发原理

要了解并发编程,需要先了解并发问题产生的原因,从原理层面理解并发。

并发与并行

并发与并行,看起来差不多,是吧,但其实是两个概念。

并发:一个处理器同时处理多个任务。
并行:多个处理器或者是多核的处理器同时处理多个不同的任务.
前者是逻辑上的同时发生(simultaneous),而后者是物理上的同时发生.

并发性(concurrency),又称共行性,是指能处理多个同时性活动的能力,并发事件之间不一定要同一时刻发生。
并行(parallelism)是指同时发生的两个并发事件,具有并发的含义,而并发则不一定并行。
来个比喻:并发和并行的区别就是一个人同时吃三个馒头和三个人同时吃三个馒头。

Erlang 之父 Joe Armstrong 用一张5岁小孩都能看懂的图解释了并发与并行的区别:

Java 内存模型

java 内存模型是屏蔽了底层硬件环境的差异而给 java 程序提供的统一的内存访问模式,可以认为是一种虚拟内存环境。在 java 程序中,所有线程都共享主内存,但是对于每一个线程都有自己的工作内存(一个虚拟的概念,包括寄存器、栈、写缓冲区、缓存以及其他硬件、编译器优化等),工作内存与主内存通过一些规定的操作来交互同步数据,而线程只能访问自己的内存。因此,在多线程环境下,很容易造成工作内存数据不一致而引起并发问题。

以上机制经常造成一个现象就是:当多个线程同时访问同一个内存时,在每个线程的工作内存中的缓存不一致。比如主内存地址A处的数据,在线程1中缓存为a1,在线程2中缓存为a2,开始时a1=a2,但当某一个线程修改了自己工作内存中的值,却没采取相应的内存同步措施时,就会造成a地址的值在两个线程中不一样。

并发问题

如前面讲的,并发带来的问题就是数据不一致,也就是 线程安全问题:“当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象时线程安全的”

此外,多个线程之间还存在一个 线程同步问题,即线程之间如何通信协作。

以上两个问题都是 java 编程中需要解决的~!

并发工具

  • 锁(synchronized、ReentrantLock)
  • 无锁(CAS、ThreadLocal)
  • 并发集合(ConcurrentHashMap、CopyOnWriteArrayList、LinkedBlockingQueue)
  • 同步器(CountDownLatch、CyclicBarrier、Semaphore)
  • 并发框架(Executor、Fork/Join、Actor)

并发编程建议

  • 给线程命名,这样可以帮助调试
  • 使用不可变类,所有属性和类都是 final 不可变的,可以保证线程安全
  • 总是按照一个全局的固定顺序获取多把锁可以避免死锁的产生。实例可以参考经典的哲学家就餐问题
  • 最小化同步的范围,而不是将整个方法同步,只对关键部分做同步
  • 分段锁: ConcurrentHashMap 就是采用的这种方式
  • 如果可以,更偏向于使用 volatile 而不是 synchronized
  • 使用更高层次的并发工具,而不是使用 wait() 和 notify() 来现线程间通信,如 BlockingQueue、 CountDownLatch及 Semeaphore
  • 优先使用并发集合,而不是对集合进行同步,并发集合能够提供更好的可扩展性
  • 高并发场景下,慎用各种框架,直接到 Servlet层最好中没

转载请注明来源。 欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。 可以在下面评论区评论,也可以邮件至 sharlot2050@foxmail.com。

文章标题:java 并发编程

字数:1k

本文作者:夏来风

发布时间:2021-02-25, 20:41:36

原始链接:http://www.demo1024.com/blog/java-high-concurrence/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。