java并发编程的艺术——第一章总结

并发编程的挑战

1.1上下文切换

  • 1.1.1多线程一定快吗
  • 1.1.2测试上下文切换次数和时长
  • 1.1.3如何减少上下文切换
  • 1.1.4减少上下文切换实战

  支持多线程的处理器不论核心数目都支持多线程执行代码(单核心当然也支持)。

  多线程实现机制:CPU给每个线程分配CPU时间片实现。

  时间片:CPU分配给各个线程的时间。

    注:因为时间片很短,所以CPU通过不停地切换线程来执行,让我们感觉到多线程是同时执行的,时间片一般是几十毫秒(ms)

  CPU通过时间片分配算法来循环执行任务,当切换任务时,会保存上一个任务的状态,切换任务后也会加载当前任务的状态。

  上下文切换:任务从保存到再加载的过程就是一次上下文切换。

  由于有加载状态与保存状态的机制存在,上下文切换实际上会影响多线程的执行速度。

1.1.1多线程一定快吗

  从文章示例看是不一定的:即当并发执行次数较少(少于百万级别),速度较串行执行慢,出现这样的情况是由于:线程的创建与上下文切换的开销。

1.1.2测试上下文切换次数和时长

  从文章示例看:上下文切换大概一秒进行1000多次。

  使用Lmbench3测量上下文切换的时长,使用vmstat测量上下文切换的次数

  注:CS(Content Switch)表示上下文切换的次数。

1.1.3如何减少上下文切换

  方法:无锁并发编程、CAS算法、使用最少线程和使用协程。

  无锁并发编程:多线程竞争锁时,会引起上下文切换,所以在多线程处理数据时可以使用一些办法来避免使用锁。

        将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。

  CAS算法:java中的Atomic包使用CAS算法来更新数据,而不需要加锁。

  使用最少线程:避免创建不必要的线程,比如任务较少时,创建很多线程来处理,这样会导致大量线程处于等待状态。

  协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。(这个协程这里看不懂)。

1.1.4减少上下文切换实战

  这里就变到命令行操作了。具体的我就不沾了,讲一下优化思路。

  通过减少大量WAITING的线程,来减少上下文切换次数。

  他通过命令行发现了大量的闲置线程,然后发现闲置线程是线程池中的工作线程(这里说明线程池接受的任务较少,大量线程闲置),然后找到配置文件修改了线程的最大数量,然后重启线程池。

  WAITING线程少了系统上下文切换的次数就会少,因为每一次从WAITING到RUNNABLE都会进行一次上下文切换。

1.2死锁 

   首先死锁是工具,运用场景多,但是导致的问题是,一旦死锁,系统功能不可用。

  写了一段代码演示死锁,代码不沾了,记住死锁的核心原因:不同线程等待不可能释放的锁。

  一旦出现死锁,只能dump线程查看到底哪个线程出了问题(这里需要专门做一次dump线程的笔记)。

  死锁问题很严重,常用的避免方式:

    1)避免一个线程同时获取多个锁

    2)避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源

    3)尝试使用定时锁,使用lock.tryLcok(timeout)来替代使用内部锁机制。

    4)对于数据库锁,加锁和解锁必须在一个数据库连接里,否则就会出现解锁失败的情况。

1.3资源限制的挑战

  资源限制:程序的执行受限于计算机硬件资源或软件资源。

  硬件资源限制:带宽的上传/下载速度,硬盘读写速度和CPU处理速度。    软件资源限制:数据库连接数和socket连接数。

  引发的问题:程序将串行执行的部分改为并行执行后,由于资源限制还是并行执行,导致了不仅不快反而更慢(上下文切换,资源的调度都需要时间)。

  如何解决:

    硬件资源限制可以尝试集群解决。

    软件资源限制:将资源池复用。

  在资源限制的情况下进行并发编程:根据资源限制调整程序的并发度。

1.4本章总结:

  有可能是因为我的知识水平有限,这一章看起来除了一些理论的补充,看起来有点空洞的!

  也可能是目前根本没有接触过多线程的编程吧。

  不过最后作者提出了宝贵的建议:熟练使用JDK并发容器与工具类。学无止境啊。

注:本书的2、3章节由于涉及计算机与JVM的知识比较多,总结起来相对难度较大,语言也很难凝练,而且对我来说还需要很多理解所以本书从第四章开始总结,2、3章的总结会暂缓

本文内容是书中内容兼具自己的个人看法所成。可能在个人看法上会有诸多问题(毕竟知识量有限,导致认知也有限),如果读者觉得有问题请大胆提出,我们可以相互交流、相互学习,欢迎你们的到来,心成意足,等待您的评价。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏三丰SanFeng

无锁编程 - 大纲

锁的缺点 锁定被迫交出时间片。 锁定意味着阻塞,多个线程(进程)排队获取资源,无法充分发挥系统性能。 锁定的阻塞无法通过fd进行通知,对性能有进一步的影响(理想...

1947
来自专栏人人都是极客

你知道何为线程与进程吗??

什么是线程?线程与进程与有什么关系?这是一个非常抽象的问题,也是一个特别广的话题,涉及到非常多的知识。我不能确保能把它讲的话,也不能确保讲的内容全部都正确。即使...

1302
来自专栏JAVA高级架构

你知道何为线程与进程吗??

什么是线程?线程与进程与有什么关系?这是一个非常抽象的问题,也是一个特别广的话题,涉及到非常多的知识。我不能确保能把它讲的话,也不能确保讲的内容全部都正确。即使...

594
来自专栏用户画像

2.1进程与线程

在多道程序同时运行的背景下,进程之间需要共享系统资源,这样就会导致各程序在执行过程中出现相互制约的关系,程序的执行就会表现出间断性的特性。这些特性都是在程序的执...

482
来自专栏Java架构沉思录

线程与进程的前世今生

原文:http://blog.csdn.net/luoweifu/article/details/46595285 作者:luoweifu

883
来自专栏hrscy

iOS多线程

进程是指系统中正在运行的一个应用程序。每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内。

803
来自专栏三丰SanFeng

Linux性能监控 - CPU、Memory、IO、Network

一、CPU 良好状态指标 CPU利用率:User Time <= 70%,System Time <= 35%,User Time + System Time ...

5069
来自专栏用户画像

DMA方式

DMA方式是一种完全由硬件进行组信息传送的控制方式。具有程序中断方式的优点,即在数据准备阶段,CPU与外设并行工作。DMA方式在外设与内存之间开辟一条“直接数据...

401
来自专栏GreenLeaves

C# 多线程学习系列二

前台线程:前台线程一般执行重要性很高的任务,至于什么是重要性很高,这个需要结合业务综合考虑,哪些操作是当前应用程序必须执行的.

202
来自专栏杨建荣的学习笔记

数据刷新中的并行改进(三) (r5笔记第79天)

在之前的两篇【数据刷新中的并行改进(二) (r5笔记第76天)、数据刷新中的并行改进(r5笔记第72天)】中分享了数据刷新的并行改进,其实在对很多的数据表做了切...

2669

扫码关注云+社区