Java并发编程(一)——挑战

时间:2021-06-20 18:00:36

多线程一定会让程序运行更快吗?
创建线程的问题,上下文切换的问题,死锁的问题,硬件和软件资源的问题

上下文切换

即使单核的CPU也是支持多线程执行代码的,CPU给每个线程分配时间片来实现这个机制。
时间片是CPU分配给各个线程的时间,非常短,所以CPU通过不停的切换线程执行,时间片一般是几十毫秒。
CPU通过时间片分配算法来执行任务

  • 使用Lmbench3可以测量上下文切换的时长
  • 使用vmstat可以测量上下文切换的次数
    Java并发编程(一)——挑战
    CS表示上下文切换的次数

减少上下文切换

  • 无锁并发编程
    多线程竞争锁时会引起上下文切换,所以多线程处理数据时可以避免锁,如将数据的ID按照Hash算法取模分段。
  • CAS算法
    Java的Atomic包使用CAS算法来更新数据,不需要加锁。
  • 使用最少线程
    避免创建不需要的线程。
  • 协程
    在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

死锁

锁是非常有用的工具,运用场景非常丰富,但是可能会引起死锁,造成系统功能不可用。

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

资源限制的挑战

程序运行速度受限与计算机硬件资源和软件资源。比如说服务器的网络带宽时固定了,即使并发也不可能超过这个阀值;另外还有磁盘的读写,CPU的处理速度等。

并发编程中,将代码程序加快的原则是将代码中串行执行的变成并发执行,但是如果受限于资源,仍然是串行执行的,那程序不仅不会加快,反而会变慢。

对于硬件资源,可以采用集群并行执行程序,如ODPS,Hadoop等