java并发编程艺术系列-一并发编程问题与解决

杨海星      2022-06-08     759

关键词:

一、并发编程问题与解决

  • 上下文切换
  • 死锁
  • 资源限制

1.1 上下文切换

1.1.1 问题

  • CPU通过时间片分配算法来循环执行任务,当前任务一个时间片执行完后会切换到下一个 任务,要保存上一个任务的状态,有一定的开销
  • 多线程不一定快 - 因为上下文切换的开销

1.1.2 解决

  • 无锁并发编程:根据id将数据hash分配到不同线程来避免使用锁
  • CAS算法:自旋锁(注意:自旋CPU消耗大)
  • 最少线程:避免创建不需要的线程,线程越多,上下文就多,等待线程也多,切换也频繁
  • 协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

1.1.3 解决实战

  • 工具

    • 使用Lmbench3[1]可以测量上下文切换的时长。

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

    • 下面是利用vmstat测量上下文切换次数的示例。

      $ vmstat 1 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- 
      r b swpd free buff cache si so bi bo in cs us sy id wa st 
      0 0 0 127876 398928 2297092 0 0 0 4 2 2 0 0 99 0 0 
      0 0 0 127868 398928 2297092 0 0 0 0 595 1171 0 1 99 0 0 
      0 0 0 127868 398928 2297092 0 0 0 0 590 1180 1 0 100 0 0 
      0 0 0 127868 398928 2297092 0 0 0 0 567 1135 0 1 99 0 0
      

      CS(Content Switch)表示上下文切换的次数,从上面的测试结果中我们可以看到,上下文每1秒切换1000多次。

  • 1.jstack命令dump线程信息

    jstack 35031 > dump31
    
  • 2.统计线程状态

    grep java.lang.Thread.State dump31 | awk '{print $2$3$4$5}' | sort | uniq -c
    39 RUNNABLE 
    21 TIMED_WAITING(onobjectmonitor) 
    6 TIMED_WAITING(parking) 
    51 TIMED_WAITING(sleeping) 
    305 WAITING(onobjectmonitor) 
    3 WAITING(parking)
    
  • 3.打开dump文件查看WAITING(onobjectmonitor)发现是jboss线程,接收任务太少,大量线程闲着waitting

  • 4.配置jboss使用较少线程

  • 5.重新统计发现waitting少了,waitting线程少了,上下文切换就少,因为每一次从 WAITTING到RUNNABLE都会进行一次上下文的切换。可以使用vmstat命令验证一下

1.2 死锁

1.2.1 问题

  • 线程t1和线程t2互相等待对方释放锁。

1.2.2 解决

  • dump线程查看出现问题的线程 java.lang.Thread.State: BLOCKED

  • 避免一个线程同时获取多个锁。

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

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

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

1.3 资源限制

1.3.1 问题

  • 硬件资源限制:网络带宽、硬盘读写、CPU处理速度
  • 软件资源限制:连接数(数据库,socket)
  • 受限于资源,多线程程序依然在串行执行,因为增加了切换上下文和资源调度的开销,反而效率更低

1.3.1 解决

  • 硬件资源:多机部署解决
  • 软件资源:连接池、io多路复用
  • 根据资源限制调整并发配置。

java并发编程系列之三juc概述

上篇文章为解决多线程中出现的同步问题引入了锁的概念,上篇文章介绍的是Synchronized关键字锁,本篇文章介绍更加轻量级的锁Lock接口及引出JUC的相关知识。本文不力争阐释清楚JUC框架的所有内容,而是站在一定的高度下,了... 查看详情

spark系列(代码片段)

目前已经更新完《Java并发编程》,《Spring核心知识》《Docker教程》和《JVM性能优化》,都是多年面试总结。欢迎关注【后端精进之路】,轻松阅读全部文章。Java并发编程:Java并发编程系列-(1)并发编程基础Java并发编程系列-(2)线... 查看详情

spark系列(代码片段)

目前已经更新完《Java并发编程》,《JVM性能优化》,《Spring核心知识》《Docker教程》和《Spark基础知识》,都是多年面试总结。欢迎关注【后端精进之路】,轻松阅读全部文章。Java并发编程:Java并发编程系列-(1)并发编程基础Java并... 查看详情

java并发编程系列之三juc概述

上篇文章为解决多线程中出现的同步问题引入了锁的概念,上篇文章介绍的是Synchronized关键字锁,本篇文章介绍更加轻量级的锁Lock接口及引出JUC的相关知识。本文不力争阐释清楚JUC框架的所有内容,而是站在一定的高度下,了... 查看详情

《java并发编程的艺术》读后笔记-part2(代码片段)

文章目录《Java并发编程的艺术》读后笔记-part2第二章Java并发机制的底层实现原理1.volatile的应用1.1volatile的定义与实现原理2.synchronized的实现原理和应用2.1Java对象头2.2锁的升级与对比3.原子操作的实现原理3.1处理器如何实现原子... 查看详情

java并发编程与高并发解决方案

下载地址:百度网盘下载课程简介:【并发编程与高并发难题我们一起攻克】本课程将结合大量图示及代码演示,让你更容易,更系统的掌握多线程并发编程(线程安全,线程调度,线程封闭,同步容器等)与高并发处理思路与... 查看详情

java并发编程

Java并发编程(一)之前看《ThinkingInJava》时,并发讲解的挺多的,自己算是初步了解了并发。但是其讲解的不深入,自己感觉其讲解的不够好。后来自己想再学一学并发,买了《Java并发编程实战》,看了一下讲的好基础、好多的理... 查看详情

原创java并发编程系列04|java内存模型详解(代码片段)

【原创】Java并发编程系列04|Java内存模型详解收录于话题#进阶架构师|并发编程专题12个点击上方“java进阶架构师”,选择右上角“置顶公众号”20大进阶架构专题每日送达思维导图写在前面前面讲解了并发编程的三大核心问题:... 查看详情

java并发编程系列之二线程基础

上篇文章对并发的理论基础进行了回顾,主要是为什么使用多线程、多线程会引发什么问题及引发的原因,和怎么使用Java中的多线程去解决这些问题。正所谓,知其然知其所以然,这是学习一个知识遵循的原则。推荐读者先行... 查看详情

原创java并发编程系列27|concurrenthashmap(下)

【原创】Java并发编程系列27|ConcurrentHashMap(下)收录于话题#进阶架构师|并发编程专题12个点击上方“java进阶架构师”,选择右上角“置顶公众号”20大进阶架构专题每日送达2020年Java面试题库连载中【000期】Java最全面试题库思... 查看详情

java并发编程的艺术记录

模拟死锁packagecom.gjjun.concurrent;/***模拟死锁,来源于《Java并发编程的艺术》*@Authorgjjun*@Create2018/8/12**/publicclassDeadLockDemo{privatestaticStringA="A";privatestaticStringB="B";publicstaticvoidmain(String[]args){D 查看详情

《java并发编程的艺术》学习小结

java并发编程的艺术第一章并发编程的挑战上下文切换:cpu通过时间片让不同线程轮流运行,从线程状态保存到下一次线程运行这个过程就是一次上下文切换多线程并不一定比单线程快,因为多线程会有线程创建和上... 查看详情

《java并发编程的艺术》学习小结

java并发编程的艺术第一章并发编程的挑战上下文切换:cpu通过时间片让不同线程轮流运行,从线程状态保存到下一次线程运行这个过程就是一次上下文切换多线程并不一定比单线程快,因为多线程会有线程创建和上... 查看详情

java并发编程的艺术目录

第7章:JAVA中的13个原子操作类第8章:JAVA中的并发工具类第9章:JAVA中的线程池 查看详情

并发编程的挑战(java并发编程的艺术)

1.上下文切换CPU通过给每个线程分配CPU时间片来实现并发,切换过程中线程的信息从保存到再加载就是一个上下文切换。由于频繁的进行上下文切换,会消耗资源,所以并发不一定比串行快。可以通过Lmbench3测量上下文切换的时... 查看详情

《java并发编程的艺术》之councurrenthashmap(代码片段)

HashMap只是相对线程安全,如果出现数据竞争就抛出fail-fast;HashTable则将每个操作都上锁,如果有耗时的操作,那么后续的操作均会被阻塞,大大降低程序的吞吐率。而ConcurrentHashMap正是为了解决这样一个问题而出现的。ConcurrentHa... 查看详情

《java并发编程的艺术》epub下载在线阅读,求百度网盘云资源

《Java并发编程的艺术》(方腾飞)电子书网盘下载免费在线阅读资源链接:链接:https://pan.baidu.com/s/19JrldXCS7yGVJadthE2VNw提取码:1dub  书名:Java并发编程的艺术作者:方腾飞豆瓣评分:7.4出版社:机械工业出版社出版年份... 查看详情

java并发编程的艺术,解读并发编程的优缺点(代码片段)

并发编程的优缺点使用并发的原因多核的CPU的背景下,催生了并发编程的趋势,通过并发编程的形式可以将多核CPU的计算能力发挥到极致,性能得到提升。在特殊的业务场景下先天的就适合于并发编程。比如在图像处理领域,一... 查看详情