1. LockSupport简介

在之前介绍AQS的底层实现,已经在介绍java中的Lock时,比如ReentrantLock,ReentReadWriteLocks,已经在介绍线程间等待/通知机制使用的Condition时都会调用LockSupport.park()方法和LockSupport.unpark()方法。而这个在同步组件的实现中被频繁使用的LockSupport到底是何方神圣,现在就来看看。LockSupport位于java.util.concurrent.locks包下,有兴趣的可以直接去看源码,该类的方法并不是很多。LockSupprot是线程的阻塞原语,用来阻塞线程和唤醒线程。每个使用LockSupport的线程都会与一个许可关联,如果该许可可用,并且可在线程中使用,则调用park()将会立即返回,否则可能阻塞。如果许可尚不可用,则可以调用 unpark 使其可用。但是注意许可不可重入,也就是说只能调用一次park()方法,否则会一直阻塞。

2. LockSupport方法介绍

LockSupport中的方法不多,这里将这些方法做一个总结:

阻塞线程

  1. void park():阻塞当前线程,如果调用unpark方法或者当前线程被中断,可以从park()方法中返回(park()后面的方法能被继续执行)

  2. void park(Object blocker):功能同方法1,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;

  3. void parkNanos(long nanos):阻塞当前线程,最长不超过nanos纳秒,增加了超时返回的特性;

  4. void parkNanos(Object blocker, long nanos):功能同方法3,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;

  5. void parkUntil(long deadline):阻塞当前线程,直到deadline;传入行号

  6. void parkUntil(Object blocker, long deadline):功能同方法5,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;

唤醒线程

7.void unpark(Thread thread):唤醒处于阻塞状态的指定线程

实际上LockSupport阻塞和唤醒线程的功能是依赖于sun.misc.Unsafe,这是一个很底层的类,有兴趣的可以去查阅资料,比如park()方法的功能实现则是靠unsafe.park()方法。另外在阻塞线程这一系列方法中还有一个很有意思的现象就是,每个方法都会新增一个带有Object的阻塞对象的重载方法。那么增加了一个Object对象的入参会有什么不同的地方了?示例代码很简单就不说了,直接看dump线程的信息。

调用park()方法dump线程

"main" #1 prio=5 os_prio=0 tid=0x02cdcc00 nid=0x2b48 waiting on condition [0x00d6f000]
  java.lang.Thread.State: WAITING (parking)
       at sun.misc.Unsafe.park(Native Method)
       at java.util.concurrent.locks.LockSupport.park(LockSupport.java:304)
       at learn.LockSupportDemo.main(LockSupportDemo.java:7)

调用park(Object blocker)方法dump线程

"main" #1 prio=5 os_prio=0 tid=0x0069cc00 nid=0x6c0 waiting on condition [0x00dcf000]
  java.lang.Thread.State: WAITING (parking)
       at sun.misc.Unsafe.park(Native Method)
       - parking to wait for  <0x048c2d18> (a java.lang.String)
       at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
       at learn.LockSupportDemo.main(LockSupportDemo.java:7)

通过分别调用这两个方法然后dump线程信息可以看出,带Object的park方法相较于无参的park方法会增加 parking to wait for <0x048c2d18> (a java.lang.String)的信息,这种信息就类似于记录“案发现场”,有助于工程人员能够迅速发现问题解决问题。有个有意思的事情是,我们都知道如果使用synchronzed阻塞了线程dump线程时都会有阻塞对象的描述,在java 5推出LockSupport时遗漏了这一点,在java 6时进行了补充。还有一点需要需要的是:synchronzed致使线程阻塞,线程会进入到BLOCKED状态,而调用LockSupprt方法阻塞线程会致使线程进入到WAITING状态。

3. 一个例子

用一个很简单的例子说说这些方法怎么用。

public class LockSupportDemo {
   public static void main(String[] args) {
       Thread thread = new Thread(() -> {
           LockSupport.park();
           System.out.println(Thread.currentThread().getName() + "被唤醒");
      });
       thread.start();
       try {
           Thread.sleep(3000);
      } catch (InterruptedException e) {
           e.printStackTrace();
      }
       LockSupport.unpark(thread);
  }
}

thread线程调用LockSupport.park()致使thread阻塞,当mian线程睡眠3秒结束后通过LockSupport.unpark(thread)方法唤醒thread线程,thread线程被唤醒执行后续操作。另外,还有一点值得关注的是,LockSupport.unpark(thread)可以指定线程对象唤醒指定的线程

13.LockSupport工具的更多相关文章

  1. Java的LockSupport工具,Condition接口和ConditionObject

    在之前我们文章(关于多线程编程基础和同步器),我们就接触到了LockSupport工具和Condition接口,之前使用LockSupport工具来唤醒阻塞的线程,使用Condition接口来实现线程 ...

  2. Java并发包源码学习系列:挂起与唤醒线程LockSupport工具类

    目录 LockSupport概述 park与unpark相关方法 中断演示 blocker的作用 测试无blocker 测试带blocker JDK提供的demo 总结 参考阅读 系列传送门: Jav ...

  3. java高并发系列 - 第14天:JUC中的LockSupport工具类,必备技能

    这是java高并发系列第14篇文章. 本文主要内容: 讲解3种让线程等待和唤醒的方法,每种方法配合具体的示例 介绍LockSupport主要用法 对比3种方式,了解他们之间的区别 LockSuppor ...

  4. 了解LockSupport工具类

    介绍: 在网上也没有找到太多的东西,大概说了一下,这个工具类的所有方法都是静态的,底层采用UNSAFE直接操作的内存,可以实现线程的阻塞和唤醒 可以看到他的park方法调用的是UNSAFE的park方 ...

  5. java中线程的停止以及LockSupport工具类

    看jstack输出的时候,可以发现很多状态都是TIMED_WAITING(parking),如下所示: "http-bio-8080-exec-16" #70 daemon pri ...

  6. 我的第一个python web开发框架(13)——工具函数包说明(四)

    string_helper.py是字符串操作包,主要对字符串进行检查.过滤和截取等处理. #!/usr/bin/evn python # coding=utf-8 import re def chec ...

  7. Java多线程系列——线程阻塞工具类LockSupport

    简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执 ...

  8. java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能

    这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...

  9. java高并发系列 - 第16天:JUC中等待多线程完成的工具类CountDownLatch,必备技能

    这是java高并发系列第16篇文章. 本篇内容 介绍CountDownLatch及使用场景 提供几个示例介绍CountDownLatch的使用 手写一个并行处理任务的工具类 假如有这样一个需求,当我们 ...

随机推荐

  1. ActiveMQ简单入门

    一.创建一个简单的Hello World案例 首先需要导入activemq-all-5.14.5.jar包,写生产端: package com.ietree.mq.helloworld; import ...

  2. SCADA 必备函数之 :关于消息的函数

    Message Functions BroadcastSystemMessage//是将一条系统消息广播给系统中所有的顶级窗口. BroadcastSystemMessageEx//将消息发送到指定的 ...

  3. The Jordan 3lab5 is the perfect sneaker for you

    The Jordan 5 3Lab5 Metallic Silver returns inside a mind-turning new iteration for that Spring/Summe ...

  4. Restful风格API

    一:协议 API与用户的通信协议,总是使用HTTPS协议. 二:域名 应该尽量将API部署在专用域名之下. https://api.example.com 如果确定API很简单,不会有进一步扩展,可以 ...

  5. Linux 实时性能测试工具——Cyclictest

    Cyclictest 是 rt-tests 下的一个测试工具,也是rt-tests 下使用最广泛的测试工具,一般主要用来测试使用内核的延迟,从而判断内核的实时性. 1.2 cyclictest 安装 ...

  6. Cloudera Manager安装之时间服务器和时间客户端(二)

    福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑         Java全栈大联盟   ...

  7. GridView自定义自增长的 序号 列

    如图所示,添加一个普通列(非模板列),将其显示文本为    序号 在GridView的RowDataBound事件中作如下处理 后台.CS 代码:

  8. 20145103《JAVA程序设计》第十周学习总结

    网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大部分的程序设 ...

  9. 20145322 《Java程序设计》第7周学习总结

    20145322何志威 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 如果使用JDK8的话,可以使用Lambda特性去除重复的信息. 在只有Lambda表达式的情况下,参 ...

  10. 20145324 《Java程序设计》第1周学习总结

    20145324 <Java程序设计>第1周学习总结 教材学习内容总结 1.Java是程序语言.标准规范.代表解决问题的平台 2.三大平台:Java SE(JVM.JRE.JDK与Java ...