【并发】3、LockSupport阻塞与唤醒,相较与wait和notify
我们可以使用wait和notify分别对象线程进行阻塞或者唤醒,但是我们也可以使用LockSupport实现一样的功能,并且在实际使用的时候,个人感觉LockSupport会更加顺手
范例1,wait与notify
class WaitTest1 {
static class ThreadA extends Thread {
public ThreadA(String name) {
super(name);
}
@Override
public void run() {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + " wakup others");
this.notify(); // 唤醒当前线程对象
for (int i = 0; i < 10; ++i) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("唤醒当前线程对象之后" + i);
}
}
for (int i = 0; i < 10; ++i) {
System.out.println("唤醒当前线程对象,释放锁之后前" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("唤醒当前线程对象,释放锁之后" + i);
}
}
}
public void mian1() {
ThreadA ta = new ThreadA("ta");
//因为wait需释放锁,所以必须在synchronized中使用(没有锁定则么可以释放?没有锁时使用会抛出IllegalMonitorStateException(正在等待的对象没有锁))
synchronized (ta) {
try {
System.out.println(Thread.currentThread().getName() + " start ta");
ta.start();
System.out.println(Thread.currentThread().getName() + " block");
// 主线程等待,释放当前线程锁
ta.wait();
System.out.println(Thread.currentThread().getName() + " continue");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

运行结果:

范例2,locksupport
class LockSupportTest1 {
private static Thread mainThread;
static class ThreadA extends Thread {
public ThreadA(String name) {
super(name);
}
@Override
public void run() {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + " wakup others");
// this.notify(); // 唤醒当前线程对象
LockSupport.unpark(mainThread); //this,这里就不能使用this了,如果这里使用this,那么其实并没有释放这个对象的锁,释放的对象是ta的锁,那就会造成死锁
for (int i = 0; i < 10; ++i) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("唤醒当前线程对象之后" + i);
}
}
for (int i = 0; i < 10; ++i) {
System.out.println("唤醒当前线程对象,释放锁之后前" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("唤醒当前线程对象,释放锁之后" + i);
}
}
}
public void main1() {
ThreadA ta = new ThreadA("LockSupportTest1");
//获取当前主线程对象
mainThread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + " start ta");
ta.start();
System.out.println(Thread.currentThread().getName()+" block");
//对主线程进行阻塞
LockSupport.park(mainThread);
System.out.println(Thread.currentThread().getName()+" continue");
}
}

效果展示:

两者相比我们就会发现,
1、locksupport不需要先进入对应的同步锁,也就是synchronize获取当前锁,然后才能使用wait进行释放
2、locksupport不局限在本线程中,更感觉是跳脱在线程外,对线程进行操控,不想synchronize中的notify,在没有退出同步代码块之前,这个锁实际上还是当前线程占用的,不管是否执行了notify
只有在退出了同步代码块,这个锁才会真正的被释放
【并发】3、LockSupport阻塞与唤醒,相较与wait和notify的更多相关文章
- 阻塞和唤醒线程——LockSupport功能简介及原理浅析
目录 1.LockSupport功能简介 1.1 使用wait,notify阻塞唤醒线程 1.2 使用LockSupport阻塞唤醒线程 2. LockSupport的其他特色 2.1 可以先唤醒线程 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- Java并发框架——AQS之阻塞与唤醒
根据前面的线程阻塞与唤醒小节知道,目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合.wait与notify组合.park与unpark组合.其中suspend与r ...
- 多线程之Java线程阻塞与唤醒
线程的阻塞和唤醒在多线程并发过程中是一个关键点,当线程数量达到很大的数量级时,并发可能带来很多隐蔽的问题.如何正确暂停一个线程,暂停后又如何在一个要求的时间点恢复,这些都需要仔细考虑的细节.在Java ...
- 从JDK源码角度看线程的阻塞和唤醒
目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合.wait与notify组合.park与unpark组合.其中suspend与resume因为存在无法解决的竟态问 ...
- 深入理解Object提供的阻塞和唤醒API
深入理解Object提供的阻塞和唤醒API 前提 前段时间花了大量时间去研读JUC中同步器AbstractQueuedSynchronizer的源码实现,再结合很久之前看过的一篇关于Object提供的 ...
- J.U.C之AQS:阻塞和唤醒线程
此篇博客所有源码均来自JDK 1.8 在线程获取同步状态时如果获取失败,则加入CLH同步队列,通过通过自旋的方式不断获取同步状态,但是在自旋的过程中则需要判断当前线程是否需要阻塞,其主要方法在acqu ...
- Java并发编程:阻塞队列(转载)
Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...
- 【转】Java并发编程:阻塞队列
在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程 ...
随机推荐
- jQuery Growl插件(消息提醒)
ps:菜鸟教程 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <s ...
- 组合数C(n,m)的四种求解方法
转自:文章 1.暴力求解 C(n,m)=n*(n-1)*...*(n-m+1)/m!,(n<=15): int CF(int n,int m) { ,i,j; ;i--) ans*=i; ;i- ...
- spring cloud 组件图
spring cloud 提供了一套微服务的框架. 上图就是微服务一些常用的组件. 1.EureKa 实现服务的注册和发现. 2.Ribbon 实现服务的调用(客户端实现负载均衡) 3.Feign 实 ...
- 菜品识别 SDK调用
from aip import AipImageClassify import os """ 填入参数 """ APP_ID = 'your ...
- vue +bootstrap 写的小例子
最近vue挺火,最近也不是特别忙,就学习了下. vue和angular非常像都是MVVM.道理都是想通的,就是语法的差异 我觉得vue和angular区别: 1.vue更轻,更便捷,适用于移动开发 2 ...
- stm32的gpio函数介绍
一.gpio_init函数 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) 调用时的格式一般是例如 RCC ...
- (树)Subtrees -- hdu -- 5524
http://acm.hdu.edu.cn/showproblem.php?pid=5524 Subtrees Time Limit: 2000/1000 MS (Java/Others) Me ...
- noip第3课资料
- WP8整合Bing应用,生活有求Bing
在Windows 8中,Bing应用一直随系统而存在,提供多样化的资讯.它们是我的“御用”App,因为可以根据我的使用习惯对应用进行定制. 在Windows Phone 8系统第三次官方更新之后, B ...
- codeforces 877b
B. Nikita and string time limit per test 2 seconds memory limit per test 256 megabytes input standar ...