广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java并发编程系列之LockSupport的用法
  • 176
分享到

Java并发编程系列之LockSupport的用法

2024-04-02 19:04:59 176人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录1、什么是LockSupport?2、两类基本api3、LockSupport本质4、LockSupport例子5、LockSupport源码总结 1、什么是LockSu

1、什么是LockSupport?

LockSupport是用于创建和其他同步类的基本线程阻塞原语

2、两类基本API

LockSupport提供了两类最基本的API:

block线程类:一般都是以pack开头的方法名,pack*(...)

pack方法有两个重载的版本:blocker是一个对象,用于指定阻塞哪个对象。不知道的情况,默认以锁对象自己this为blocker


public static void park();
public static void park(Object blocker);

拓展parkNanos函数


public static void parkNanos(Object blocker, long nanos) {
    if (nanos > 0) { 
        // 获取当前线程
        Thread t = Thread.currentThread();
        // 设置Blocker
        setBlocker(t, blocker);
        // 获取许可,并设置了时间
        UNSAFE.park(false, nanos);
        // 设置许可,重新设置blocker为null,避免unpack,获取的blocker为之前设置的
        setBlocker(t, null);
    }
}

nanos参数表示相对时间,表示等待多长时间

parkUntil函数:表示在指定的时限前禁用当前线程,deadline参数表示绝对时间,表示指定的时间


public static void parkUntil(Object blocker, long deadline) {
    // 获取当前线程
    Thread t = Thread.currentThread();
    // 设置Blocker
    setBlocker(t, blocker);
    UNSAFE.park(true, deadline);
    // 设置Blocker为null
    setBlocker(t, null);
}

unBlock线程类:unpack(Thread)

unpack方法用于释放许可,指定线程可以继续运行。

3、LockSupport本质

LockSupport是一个许可的信号量机制,pack消费,unpack放入,放入也是仅一个,不累计。例如,调用unpack放入一个信号量,多次调用,这个是不会累计信号量的,pack调用之后会消费

4、LockSupport例子

例子:如何控制两个线程依次打印1、2、3、4、5、6、…


import java.util.concurrent.locks.LockSupport;
public class LockSupportExample {
    private static final int total = 10;
    private  static int i = 0;
    static Thread t1 , t2;
    public static void main(String[] args) {
        t1 = new Thread(() ->{
            while (i < total) {
                System.out.println("t1:" + (++i));
                LockSupport.unpark(t2);
                LockSupport.park();
            }
        });
        t2 = new Thread(() -> {
            while (i < total) {
                LockSupport.park();
                System.out.println("t2:" + (++i));
                LockSupport.unpark(t1);
            }
        });
        t1.start();
        t2.start();
    }
}

打印:

t1: 1
t2: 2
t1:3
t2:4
t1:5
t2:6
t1:7
t2:8
t1:9
t2:10

5、LockSupport源码


public class LockSupport {
    // Hotspot implementation via intrinsics API
    private static final sun.misc.Unsafe UNSAFE;
    private static final long parkBlockerOffset;
    private static final long SEED;
    private static final long PROBE;
    private static final long SECONDARY;
    static {
        try {
            // 获取Unsafe实例
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            // 线程类的class对象
            Class<?> tk = Thread.class;
            // 获取Thread的parkBlocker字段的内存偏移地址
            parkBlockerOffset = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("parkBlocker"));
            // 获取Thread的threadLocalRandomSeed字段的内存偏移地址
            SEED = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSeed"));
            // 获取Thread的threadLocalRandomProbe字段的内存偏移地址
            PROBE = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomProbe"));
            // 获取Thread的threadLocalRandomSecondarySeed字段的内存偏移地址
            SECONDARY = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
        } catch (Exception ex) { throw new Error(ex); }
    }
}

pack方法的源码:


public static void park(Object blocker) {
    // 获取当前线程
    Thread t = Thread.currentThread();
    // 设置Blocker
    setBlocker(t, blocker);
    // 获取许可
    UNSAFE.park(false, 0L);
    // 重新可运行后再此设置Blocker为null,避免unpack获取到上一个设置的setBlocker(t, blocker);
    setBlocker(t, null);
}

unpack的源码:


public static void unpark(Thread thread) {
    if (thread != null) // 线程为不空
        UNSAFE.unpark(thread); // 释放该线程许可
}

可以看出,不管是pack的源码还是unpack的源码都是通过Unsafe的底层api实现的

sun.misc.Unsafe可以直接进行底层非安全操作的工具

主要提供如下操作:

  • 线程挂起与恢复
  • CAS操作
  • 操纵对象属性
  • 操纵数组元素
  • 直接操纵内存

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Java并发编程系列之LockSupport的用法

本文链接: https://www.lsjlt.com/news/158020.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java并发编程系列之LockSupport的用法
    目录1、什么是LockSupport?2、两类基本API3、LockSupport本质4、LockSupport例子5、LockSupport源码总结 1、什么是LockSu...
    99+
    2022-11-12
  • Java并发编程之LockSupport类详解
    目录一、LockSupport类的属性二、LockSupport类的构造函数三、park(Object blocker)方法 和 park()方法分析四、parkNanos(Obje...
    99+
    2022-11-12
  • Java并发编程中LockSupport的用法是怎样的
    Java并发编程中LockSupport的用法是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1、什么是LockSupportLockSupport是用于创建锁和其他同步...
    99+
    2023-06-25
  • 怎么在Java中利用LockSupport类实现并发编程
    今天就跟大家聊聊有关怎么在Java中利用LockSupport类实现并发编程,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、LockSupport类的属性private ...
    99+
    2023-06-15
  • Java并发编程之ConcurrentLinkedQueue队列详情
    ConcurrentLinkedQueue JDK中提供了一系列场景的并发安全队列。总的来说,按照实现方式的不同可分为阻塞队列和非阻塞队列,前者使用锁实现,而后则使用CAS非阻塞算法...
    99+
    2022-11-13
  • Java并发编程之LinkedBlockingQueue队列怎么使用
    这篇文章主要介绍了Java并发编程之LinkedBlockingQueue队列怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java并发编程之LinkedBlockingQueue队列怎么使用文章都会有...
    99+
    2023-06-30
  • Java并发编程之阻塞队列(BlockingQueue)详解
    目录队列阻塞队列ArrayBlockingQueue重要属性构造方法添加元素add(e)offer(e)put(e)offer(e,time,unit)移除元素take()deque...
    99+
    2022-11-12
  • 深入理解Java并发编程之LinkedBlockingQueue队列
    前面一篇文章我们介绍了使用CAS算法实现的非阻塞队列ConcurrentLinedQueue, 下面我们来介绍使用独占锁实现的阻塞队列LinkedBlockingQueue。 Lin...
    99+
    2022-11-13
  • Java并发编程之CountDownLatch的使用
    目录前言基本使用await尝试获取锁获取锁失败countDown方法前言 CountDownLatch是一个倒数的同步器,和其他同步器不同的是,state为0时表示获取锁成功。常用来...
    99+
    2023-05-20
    Java并发编程CountDownLatch Java CountDownLatch使用 Java CountDownLatch
  • Java并发编程之阻塞队列深入详解
    目录1. 什么是阻塞队列2. 阻塞队列的代码使用3. 生产者消费者模型(1)应用一:解耦合(2)应用二:削峰填谷(3)相关代码4.阻塞队列和生产者消费者模型功能的实现1. 什么是阻塞...
    99+
    2022-11-12
  • Java并发编程之Exchanger方法详解
    简介 Exchanger是一个用于线程间数据交换的工具类,它提供一个公共点,在这个公共点,两个线程可以交换彼此的数据。 当一个线程调用exchange方法后将进入等待状态,直到另外一...
    99+
    2022-11-12
  • java并发编程工具类JUC之LinkedBlockingQueue链表队列
    java.util.concurrent.LinkedBlockingQueue 是一个基于单向链表的、范围任意的(其实是有界的)、FIFO阻塞队列。访问与移除操作是在队头进行,添...
    99+
    2022-11-12
  • Java并发编程之JUC并发核心AQS同步队列原理剖析
    目录一、AQS介绍二、AQS中的队列1、同步等待队列2、条件等待队列3、AQS队列节点Node三、同步队列源码分析1、同步队列分析2、同步队列——独占模式源码分析3、同步队列——共享...
    99+
    2022-11-12
  • Java并发编程之Semaphore的使用简介
    目录简介Semaphored的使用构造方法核心方法示例使用Semaphore实现互斥简介 Semaphore是用来限制访问特定资源的并发线程的数量,相对于内置锁synchroniz...
    99+
    2022-11-12
  • Java并发编程之Executor接口的使用
    一、Executor接口的理解 Executor属于java.util.concurrent包下; Executor是任务执行机制的核心接口; 二、Executo...
    99+
    2022-11-12
  • 怎么用Java高并发编程之CountDownLatch
    本篇文章为大家展示了怎么用Java高并发编程之CountDownLatch,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。什么是CountDownLatchCountDownLatch是通过一个计数器...
    99+
    2023-06-15
  • Java并发编程之线程间的通信
    目录一、概念简介1、线程通信2、等待通知机制3、基础方法二、等待通知原理1、基本原理2、实现案例三、管道流通信1、管道流简介2、使用案例四、生产消费模式1、业务场景2、代码实现五、源...
    99+
    2022-11-12
  • Java并发编程之对象的共享
    目录1.可见性1.1 失效数据1.2 非原子的64位操作1.3 加锁和可见性1.4 volatile变量2. 发布与泄露3. 线程封闭3.1 Ad-hoc线程封闭3.2 栈封闭3.3...
    99+
    2022-11-13
  • Java并发编程之对象的组合
    目录1. 设计线程安全的类1.1 收集同步需求1.2 依赖状态的操作1.3 状态的所有权2. 实例封闭2.1 Java监视器模式3. 线程安全性的委托3.1 基于委托的车辆追踪器3....
    99+
    2022-11-13
  • Java并发编程之工具类Semaphore的使用
    一、Semaphore的理解 Semaphore属于java.util.concurrent包; Semaphore翻译成字面意思为信号量,Semaphore可以控...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作