zoukankan      html  css  js  c++  java
  • JAVA多线程之park & unpack

    一、park & unpack demo

    main-start 时间Thu May 13 16:17:32 CST 2021
    Thread-0
    main-end 时间Thu May 13 16:17:33 CST 2021

    特点:该方式实现线程的通信不需要锁,并且可以唤醒指定的线程

    Object.wait()、Object.notify() :

    • wait和notify都是Object中的方法,在调用这两个方法前必须先获得锁对象,这限制了其使用场合:只能在同步代码块中。
    • 当对象的等待队列中有多个线程时,notify只能随机选择一个线程唤醒,无法唤醒指定的线程。

    二、LockSupport阻塞和唤醒线程原理

    LockSupport是通过控制变量_counter来对线程阻塞唤醒进行控制的。原理有点类似于信号量机制。但是_counter的值只有0或者1

    当调用park()方法时,会将_counter置为0,同时判断前值,等于0说明前面被park过,则直接进入排队,否则将使该线程阻塞。
    当调用unpark()方法时,会将_counter置为1,同时判断前值,小于1会进行线程唤醒,否则直接退出。
    形象的理解,线程阻塞需要消耗凭证(permit),这个凭证最多只有1个。当调用park方法时,如果有凭证,则会直接消耗掉这个凭证然后正常退出;但是如果没有凭证,就必须阻塞等待凭证可用;而unpark则相反,它会增加一个凭证,但凭证最多只能有1个。
    为什么可以先唤醒线程后阻塞线程?
    因为unpark获得了一个凭证,之后调用park因为有凭证消费,故不会阻塞。
    为什么唤醒两次后阻塞两次会阻塞线程。
    因为凭证的数量最多为1,连续调用两次unpark和调用一次unpark效果一样,只会增加一个凭证;而调用两次park却需要消费两个凭证,但我们有且只有一个凭证。

    古之学者为己,今之学者为人
  • 相关阅读:
    Epoll技术深入学习
    nginx
    epoll案例
    Linux网络编程初步
    链表快速排序(已通过ACM在线评测)
    C++内存管理
    c++11并发语法初步
    数据库与SQL优化笔记(一)
    C++面向对象模型(虚表与虚表指针)
    c++的一些杂项
  • 原文地址:https://www.cnblogs.com/jalja365/p/14765373.html
Copyright © 2011-2022 走看看