美文网首页我爱编程
并发编程笔记1

并发编程笔记1

作者: 笨手笨脚越 | 来源:发表于2018-05-27 20:31 被阅读30次

    上下文切换

    单核处理器是如何支持多线程编程的? CPU通过给每个线程分配CPU时间片来实现。

    • 时间片是CPU分配给各个线程的时间,时间片非常短,CPU通过不停切换线程执行,切换时间很快,让人感觉是在同时执行。
    • CPU通过时间片算法来循环执行任务,当前任务执行完一个时间片后会切换到下一个任务,切换前辉保存上一个任务的状态,便于下次切回的时候可以再加载这个任务的状态。任务从保存到再加载的过程就是一次上下文切换。
    • 因为线程有创建和上下文的切换的开销,并发执行累加操作次数没有很高的时候,速度会比串行执行慢。

    测试上下文切换次数和时长的工具

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

    如何减少上下文切换

    • 无锁并发编程。多线程竞争锁时,会引起上下文切换,可以用些方法来避免用锁。比如对数据id计算取模分段,不同线程处理不同段的数据。
    • CAS算法。CAS:Compare and Swap, 翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁。
    • 使用最少线程。避免创建不需要的线程。比如任务很少,不比创建大量线程,可能会导致大量线程处于等待状态。
    • 协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。具体java如何实现协程要找个时间研究下。

    死锁

    dump分析死锁

    • 一旦出现死锁,业务是可感知的,不能继续提供服务。只能通过dump线程查看是哪个线程出现了问题。
    • Jstack是JDK自带的命令行工具,主要用于线程Dump分析
    1. 我们先用Jps来查看java进程id(或者Linux的ps命令)


      image.png
    2. jstack的使用


      image
    3. jstack输出线程dump信息到文件


      image
    4. 查看文件,关键字是at DeadThread.run,比如at DeadThread.run(DeadThread.java:37),说明Thread-1实在DeadThread类的37行处发生死锁


      image.png

    避免死锁的常见方法

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

    相关文章

      网友评论

        本文标题:并发编程笔记1

        本文链接:https://www.haomeiwen.com/subject/egkijftx.html