LockSuport
1.Java_第一季_JAVASE_自增、单例模式、类与实例初始化过程、方法参数传递机制、递归和迭代、成员变量与局部变量2.Java_第一季_SSM_Spring Bean的作用域、Spring事务的传播行为、Spring MVC的执行流程、3.Java_第一季_java高级_Redis持久化、MySql何时建立索引4.java_JUC、volatile5.java_CAS6.java_阻塞队列(FIFO先进先出)7.JUC下countDownLatch、CyclicBarrier、Semaphore以及枚举的常见使用方法8.java_锁9.java_集合不安全10.Spring循环依赖11.AbstractQueuedSynchronizer---AQS
12.LockSuport
13.java_线程池7大参数_底层运行原理14.java_线程池三个常用方式15.Java_Callable<V>的基本使用16.java_锁_synchronized与Lock的区别17.java_强、软、弱、虚四大引用18.java_OOM19.JAVA-interview20.java_NIO21.java_JVM之GC22.java_JVM23.单例模式设计24.netty服务端、客户端简单搭建25.java使用webSocket与前端通讯26.java串口通讯27.用Java读取文件文字并语音播报28.Proguard-混淆29.Spring Security30.MQ31.spring相关面试题32.执行jar包33.Spring34.SpringBoot数据访问35.Java Stream(流)基本使用36.java集合工具类 Collections基本使用37.LocalDateTime、LocalDate、Date、String相互转化38.java8新特性39.java设计模式40.java springboot使用定时器41.MQ根据正常队列、死信队列来实现延迟队列的场景java.util.concurrent.locks.LockSuport
-
用于创建锁和其他同步类的基本线程阻塞原语。
这个类与每个使用它的线程相关联,一个许可证(在
Semaphore
类的意义上)。 如果许可证可用,则呼叫park
将park
返回,在此过程中消耗它; 否则可能会阻止。 致电unpark
使许可证可用,如果尚不可用。 (与信号量不同,许可证不能累积,最多只有一个。)方法
park
和unpark
提供了阻止和解除阻塞线程的有效手段,该方法不会遇到导致不推荐使用的方法Thread.suspend
和Thread.resume
目的不能使用的问题:一个线程调用park
和另一个线程之间的尝试unpark
线程将保持活跃性,由于许可证。 另外,如果调用者的线程被中断,park
将返回,并且支持超时版本。park
方法也可以在任何其他时间返回,因为“无理由”,因此一般必须在返回之前重新检查条件的循环中被调用。 在这个意义上,park
作为一个“忙碌等待”的优化,不浪费时间旋转,但必须与unpark
配对才能有效。park
的三种形式也支持blocker
对象参数。 线程被阻止时记录此对象,以允许监视和诊断工具识别线程被阻止的原因。 (此类工具可以使用方法getBlocker(Thread)
访问阻止程序 。)强烈鼓励使用这些形式而不是没有此参数的原始形式。 在锁实现中作为blocker
提供的正常参数是this
。这些方法被设计为用作创建更高级同步实用程序的工具,并且本身对于大多数并发控制应用程序本身并不有用。
park
方法仅用于形式的构造:while (!canProceed()) { ... LockSupport.park(this); }
canProceed
也没有任何其他动作之前的呼叫park
需要锁定或阻止。 因为只有一个许可证与每个线程相关联,park
任何中介使用可能会干扰其预期效果。
三种让线程等待和唤醒的方法:
1、使用 Object 中的 wait() 方法让线程等待,使用Object中的 notify() 方法唤醒线程;
public class LockSupperDemo { public static Object object = new Object(); public static void main(String[] args) { /** * 1、wait()和 notify()必须放在synchronized同步代码块中执行, * 否则会报错:java.lang.IllegalMonitorStateException * * 2、wait()和 notify()成对出现,并且必须先等待再唤醒,线程才能够被唤醒 */ new Thread(() -> { synchronized (object) { System.out.println(Thread.currentThread().getName() + "\t come in"); try { object.wait();//阻塞 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "\t 被唤醒"); } }, "A").start(); new Thread(() -> { synchronized (object) { object.notify();//唤醒 System.out.println(Thread.currentThread().getName() + "\t 唤醒动作"); } }, "B").start(); } }
2、使用 JUC 中的 Condition 的 await() 方法让线程等待,使用 signal() 方法唤醒线程;
public static Lock lock = new ReentrantLock(); public static Condition condition = lock.newCondition(); public static void main(String[] args){ /** * 1、await()和 signal()必须放在 lock 代码块中执行, * 否则会报错:java.lang.IllegalMonitorStateException * * 2、await()和 signal()必须先等待再唤醒,线程才能够被唤醒 */ new Thread(() ->{ lock.lock(); try { System.out.println(Thread.currentThread().getName() + "\t come in"); condition.await();//等待 System.out.println(Thread.currentThread().getName() + "\t 被唤醒"); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } },"A").start(); new Thread(() -> { lock.lock(); try { condition.signal();//唤醒 System.out.println(Thread.currentThread().getName() + "\t 唤醒动作"); }finally { lock.unlock(); } }, "B").start(); }
3、使用 LockSupport 类可以阻塞当前线程以及唤醒指定被阻塞的线程;
static void |
park()
禁止当前线程进行线程调度,除非许可证可用。
|
static void |
park(Object blocker)
禁止当前线程进行线程调度,除非许可证可用。
|
static void |
LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,每个线程都有一个许可(permit);
permit只有两个值 0和1,默认为0;
public static void main(String[] args){ /** * 1、不需要放在锁代码块中 * * 2、先唤醒后阻塞,线程照样执行 */ Thread a = new Thread(() ->{ System.out.println(Thread.currentThread().getName() + "\t come in"); LockSupport.park();//阻塞。。需要一个许可证 System.out.println(Thread.currentThread().getName() + "\t 被唤醒"); },"a"); a.start(); new Thread(() ->{ LockSupport.unpark(a);//给a线程发放许可证 System.out.println(Thread.currentThread().getName() + "\t 唤醒动作"); },"B").start(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?