zoukankan      html  css  js  c++  java
  • Java知识点梳理——多线程与并发

    第一部分:线程模型深度剖析

    一、线程的生命周期

    线程状态转换图:

    1、新建状态(New)
    用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)。
    注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadStateException异常。

    2、就绪状态(Runnable)
    处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线 程就绪队列(尽管是采用队列形式,事实上,把它称为可运行池而不是可运行队列。因为cpu的调度不一定是按照先进先出的顺序来调度的),等待系统为其分配 CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“cpu调 度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。
    提示:如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep()方式使主线程睡眠一伙儿,转去执行子线程。

    3、运行状态(Running)
    处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
    处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务。如果该线程失去了cpu资源,就会又从运 行状态变为就绪状态。重新等待系统分配资源。也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。

    当发生如下情况是,线程会从运行状态变为阻塞状态:
    ①、线程调用sleep方法主动放弃所占用的系统资源
    ②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞
    ③、线程试图获得一个同步监视器,但更改同步监视器正被其他线程所持有
    ④、线程在等待某个通知(notify)
    ⑤、程序调用了线程的suspend方法将线程挂起。不过该方法容易导致死锁,所以程序应该尽量避免使用该方法。
    当线程的run()方法执行完,或者被强制性地终止,例如出现异常,或者调用了stop()、desyory()方法等等,就会从运行状态转变为死亡状态。

    4、阻塞状态(Blocked)
    处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。阻塞的情况分三种:

    (1)等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
    (2)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁(synchronized)被别的线程占用,则JVM会把该线程放入锁池中。
    (3)其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。有三种方法可以暂停Threads执行。
    5、死亡状态(Dead)

    二、多线程并发中的线程安全问题

    https://blog.csdn.net/u010369338/article/details/88691988
    https://blog.csdn.net/weixin_42226129/article/details/87459374

    三、Synchronized原理分析

    https://www.cnblogs.com/jimoer/p/13664252.html
    https://blog.csdn.net/weixin_43213517/article/details/89713899

    四、Volatile原理分析

    https://www.cnblogs.com/dolphin0520/p/3920373.html

    第二部分:显示锁和AQS底层原理分析

    https://www.cnblogs.com/qlsem/p/11487783.html

    第三部分:并发容器深度剖析

    一、ConcurrentHashMap

    1、HashMap:

    在多线程环境下,put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap。

    2、HashTable:

    HashTable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下HashTable的效率非常低下。因为当一个线程访问HashTable的同步方法时,其他线程访问HashTable的同步方法时,可能会进入阻塞或轮询状态。如线程1使用put进行添加元素,线程2不但不能使用put方法添加元素,并且也不能使用get方法来获取元素,所以竞争越激烈效率越低。

    3、ConcurrentHashMap:

    https://www.cnblogs.com/yydcdut/p/3959815.html
    https://blog.csdn.net/weixin_44460333/article/details/86770169

    二、ConcurrentLinkedQueue

    https://blog.csdn.net/qq_38293564/article/details/80798310

    第四部分:CAS原子操作及相关类

    一、基本数据类型

    (1)AtomicInteger

    https://blog.csdn.net/fanrenxiang/article/details/80623884
    https://baijiahao.baidu.com/s?id=1647621616629561468&wfr=spider&for=pc

    (2)AtomicLong

    https://blog.csdn.net/weixin_42146366/article/details/87820373
    https://blog.csdn.net/weixin_42146366/article/details/105378681

    (3)AtomicBoolean

    https://baijiahao.baidu.com/s?id=1647915101064077163&wfr=spider&for=pc

    二、数组

    (1)AtomicIntegerArray

    (2)AtomicLongArray

    (3)AtomicReferenceArray

    三、引用类型

    (1)AtomicReference

    https://www.cnblogs.com/fhblikesky/p/13692643.html

    第五部分:JUC并发编程工具掌握

    (1)CountDownLatch:减法计数器

    (2)CyclicBarrier:加法计数器

    (3)Semaphore:计数信号量

    https://www.cnblogs.com/seizedays/archive/2020/03/25/12564441.html

    第六部分:JUC中的FutureTask实战

    第七部分:JDK中线程池工作机制、Fork/Join原理剖析

    https://www.cnblogs.com/zedosu/p/6665306.html

    第八部分:深入ThreadLocal底层原理及使用实战

  • 相关阅读:
    [恢]hdu 1517
    [恢]hdu 1847
    [恢]hdu 2189
    XHTML学习资料(二)
    基于ASP.NET的lucene.net全文搜索(一)
    XHTML学习资料(三)—— 表格
    ASP.NET中的Menu控件的应用
    基于ASP.NET的lucene.net全文搜索(二)
    EasyFas开源t框架说明
    动态解析XML生成EXCEL
  • 原文地址:https://www.cnblogs.com/zyzyBlog/p/14287401.html
Copyright © 2011-2022 走看看