做淘宝网站的主机,湖北网络建设公司网站,小程序制作工具,比较专业的app开发公司前言#xff1a;本文将介绍LockSupport类中的方法和部分源码#xff0c;以及面试常问到的一个小问题#xff0c;感兴趣的大佬可以指点下。 希望能够加深自己的印象以及帮助到其他的小伙伴儿们#x1f609;#x1f609;。 如果文章有什么需要改进的地方还请大佬不吝赐教本文将介绍LockSupport类中的方法和部分源码以及面试常问到的一个小问题感兴趣的大佬可以指点下。 希望能够加深自己的印象以及帮助到其他的小伙伴儿们。 如果文章有什么需要改进的地方还请大佬不吝赐教。 小威在此先感谢各位大佬啦~~ 个人主页小威要向诸佬学习呀 个人简介大家好我是小威一个想要与大家共同进步的男人 目前状况24届毕业生曾经在某央企公司实习目前在某税务公司实习 欢迎大家这里是CSDN我总结知识的地方欢迎来到我的博客我亲爱的大佬 以下正文开始
LockSupport类常用方法源码
LockSupport只是一个简单的基础类位于java.util.concurrent.locks包下多用于线程的阻塞和唤醒因此LockSupport也被称为其他线程的工具类。 LockSupport类的源码有标注LockSupport类无法实例化。LockSupport类的底层是有Unsafe类实现的LockSupport加载时的初始化也用到了Unsafe获取成员的偏移量其源码如下 // Hotspot implementation via intrinsics APIprivate 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 sun.misc.Unsafe.getUnsafe();Class? tk Thread.class;parkBlockerOffset UNSAFE.objectFieldOffset(tk.getDeclaredField(parkBlocker));SEED UNSAFE.objectFieldOffset(tk.getDeclaredField(threadLocalRandomSeed));PROBE UNSAFE.objectFieldOffset(tk.getDeclaredField(threadLocalRandomProbe));SECONDARY UNSAFE.objectFieldOffset(tk.getDeclaredField(threadLocalRandomSecondarySeed));} catch (Exception ex) { throw new Error(ex); }}LockSupport类中有一些核心的线程操作方法多用于线程的阻塞与唤醒。 调用park()方法使线程阻塞 public static void park(Object blocker) {Thread t Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, 0L);setBlocker(t, null);}private static void setBlocker(Thread t, Object arg) {// Even though volatile, hotspot doesnt need a write barrier here.UNSAFE.putObject(t, parkBlockerOffset, arg);}调用park(Object blocker)对传入的线程进行阻塞 public static void park(Object blocker) {Thread t Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, 0L);setBlocker(t, null);}在截止时间之前阻塞传入的某个线程 public static void parkUntil(Object blocker, long deadline) {Thread t Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(true, deadline);setBlocker(t, null);}在nanos的时间范围内阻塞传入的线程 public static void parkNanos(Object blocker, long nanos) {if (nanos 0) {Thread t Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, nanos);setBlocker(t, null);}}唤醒传入的线程 public static void unpark(Thread thread) {if (thread ! null)UNSAFE.unpark(thread);}wait/notify方法和park/unpark方法区别
LockSupport类中的方法还有很多在此先列举到这里。当我们看到阻塞和唤醒方法时我们会联想到另一组唤醒方法wait()和notify()这两组方法还是有所区别的。 这里直接记录下结论wait和notify方法只能在同步代码块中使用即必须与synchronized连用必须先执行wait方法然后再执行notify方法唤醒线程调换顺序的话线程仍处于阻塞状态。
而park()和unpark()方法与之不同这里可以通过代码运行结果来看
package XIAOWEI;
import java.util.concurrent.locks.LockSupport;public class Xiaowei{public static void main(String[] args) {Thread A new Thread(()- {System.out.println(线程A已经被阻塞QWQ);LockSupport.park();System.out.println(线程A被线程B唤醒啦~~~);});A.start();new Thread(()-{System.out.println(线程B在唤醒线程A ing~~~);LockSupport.unpark(A);},B).start();}
}那如果我们先通过线程B唤醒线程A然后再让线程A阻塞呢让线程A的阻塞休眠两秒
package XIAOWEI;
import java.util.concurrent.locks.LockSupport;
public class Xiaowei {public static void main(String[] args) {Thread A new Thread(()- {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(线程A已经被阻塞QWQ(第二版));LockSupport.park();System.out.println(线程A被线程B唤醒啦~~~第二版);});A.start();new Thread(()-{System.out.println(线程B在唤醒线程A ing~~~驾驾驾);LockSupport.unpark(A);},B).start();}
}由上面输出结果来看虽然线程B先唤醒了线程A然后线程A再开始阻塞但是线程A还是处于唤醒状态这是为什么呢
接下来我找了段LockSupport类中的注释其实有时看看注释也挺有意思的哈哈 * pThis class associates, with each thread that uses it, a permit* (in the sense of the {link java.util.concurrent.Semaphore* Semaphore} class). A call to {code park} will return immediately* if the permit is available, consuming it in the process; otherwise* it emmay/em block. A call to {code unpark} makes the permit* available, if it was not already available. (Unlike with Semaphores* though, permits do not accumulate. There is at most one.)这段话大意是说LockSupport类使用permits这个东西来实现线程的阻塞和唤醒。每一个线程都会使用到拥有permit且permit的值默认为0。接着它又说这个概念和Semaphore信号量差不多但是permit的值只有0和1两个值。哦~原来是这样。
对于上面例子线程B调用unpark方法唤醒A后会使得线程A的permit值为1当线程调用park方法使自己阻塞时发现自己已经有许可permit了就会继续向下执行业务而不会阻塞不动。
好了本篇文章就先分享到这里了后续会继续分享其他方面的知识感谢大佬认真读完支持咯~ 文章到这里就结束了如果有什么疑问的地方请指出诸佬们一起讨论 希望能和诸佬们一起努力今后我们顶峰相见 再次感谢各位小伙伴儿们的支持