《Java并发编程的艺术》-第一章-并发编程的挑战-读书笔记

目录

第一章

1.1上下文切换

1.1.1 多线程一定快吗

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

1.1.3如何减少上下文切换

1.1.4减少上下文切换实战

1.2死锁

1.3资源限制的挑战

1.4本章小结

参考


第一章


并发编程的目的:让程序运行更快。

但并不是启动更多的线程就能让程序最大限度并发执行。

想通过多线程让程序运行更快需要面对很多问题,比如:上下文切换问题、死锁问题、软硬件资源的限制问题等。

1.1上下文切换


一个进程可以有多个线程,即使单核处理器也可以多线程,CPU通过分配CPU时间片来实现,时间片一般是几十毫秒。

上下文切换回影响多线程的执行速度。

1.1.1 多线程一定快吗

答案是:不一定

循环次数

串行执行耗时/ms并发执行耗时并发比串行快多少
1亿13077约1倍
1千万189约1倍
1百万55差不多
10万43差不多
1万01

 

可以发现,并发执行累加操作不超过百万次时,并发比串行还要慢,是因为线程创建和上下文切换的开销。

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

  • 使用Lmbench3可以测量上下文切换时长。
  • 使用vmstat可以测量上下文切换的次数。

上下文切换1秒1000多次。

1.1.3如何减少上下文切换

方法有:

  • 无锁并发编程

多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同线程处理不同段的数据。

  • CAS算法

Java的Atomic包使用CAS算法更新数据,不需要加锁。

  • 使用最少线程

避免创建不需要的线程,否则会造成大量线程处于等待状态。

  • 使用携程

在单线程里实现多任务的调度,并在单线程中维持多任务的切换。

1.1.4减少上下文切换实战

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

  • 第一步:

用jstack命令dump线程信息,查看pid为xxxx的进程中的线程都在做什么

如何使用jstack分析线程信息

  • 第二步:

统计所有线程的状态,例如发现300多个线程处于WAITING状态

  • 第三步:

打开dump文件查看处于WAITING的线程在做什么,例如发现都是JBOSS的工作线程,说明JBOSS线程池里线程收到的任务太少。

  • 第四步:

减少JBOSS的工作线程数,找到其线程池配置信息,将maxThreads降到100。

  • 第五步:

重启,查看信息。

1.2死锁


避免死锁的几个常见方法:

  • 避免一个线程同时获取多个锁。
  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
  • 尝试使用定时锁,使用lock.tryLock(timeout)来代替使用内部锁机制。
  • 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。

1.3资源限制的挑战


(1)什么是资源限制

硬件资源限制有:带宽的上传/下载速度、硬盘读写速度、CPU处理速度。

软件资源限制有:数据库的连接数和Socket连接数等。

(2)资源限制引发的问题

资源限制可能会导致并发执行的速度低于串行。

(3)如何解决资源限制的问题

  • 对于硬件资源限制:可以考虑用集群并行执行程序。既然单机资源有限,那就让程序在多机上运行。比如使用ODPS,Hadoop或者自己搭建服务器集群,不同的机器处理不同的数据。可以通过“数据ID%机器数”,计算得到一个机器编号,对应编号的机器处理这笔数据。
  • 对于软件资源限制:可以考虑使用资源池将资源复用。比如使用连接池将数据库和Socket连接复用,或者在调用对方webservice接口获取数据时,只建立一个连接。

(4)在资源限制情况下并发编程

方法是:根据不同资源限制调整程序的并发度

比如:

下载文件程序依赖两个资源:带宽和硬盘读写速度。

有数据库操作时,涉及数据库连接数,如果SQL语句执行非常快,而线程的数量比数据库连接数大很多,则某些线程会被阻塞,等待数据库连接。

1.4本章小结


本章介绍了并发编程时可能遇到的几个挑战及解决方案,对于Java开发工程师而言,此书作者强烈推荐多使用JDK并发包提供的并发容器和工具类来解决并发问题,因为这些类经过了充分的测试和优化,均可解决本章提到的几个挑战。

 

参考

参考《Java并发编程的艺术》——方鹏飞 魏鹏 程晓明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值