【并发】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),这些工具都为我们编写多线程程 ...
随机推荐
- 2018.10.26 bzoj2721: [Violet 5]樱花(数论)
传送门 推一波式子: 1x+1y=1n!\frac 1 x+\frac 1 y=\frac 1 {n!}x1+y1=n!1 =>xy−x∗n!−y∗n!xy-x*n!-y*n!xy−x∗n ...
- 2018.10.25 bzo1227: [SDOI2009]虔诚的墓主人(组合数学+扫描线+bit)
传送门 有点难调啊.其实是我自己sb了 不过交上去1A1A1A还是平衡了一下心态. 所以这道题怎么做呢? 我们考虑对于一个点(x,y)(x,y)(x,y)如果这个点成为中心,正左/右/上/下分别有l/ ...
- js生成条形码插件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- #pragma warning(disable 4786)
#pragma warning(disable 4786) 此warning产生的原因是因为标识符过长,超过了最大限定255个字符类名超过了255个字符,使用时就会报4786的waring. 在使用S ...
- Curator之Recipes之锁
转载自:https://blog.csdn.net/kiss_the_sun/article/details/50221463 参考文档: http://ifeve.com/java_lock_see ...
- Kotlin零碎总结
1.对于Kotlin的包方法其实对应Java而言是静态方法,如Entrance.kt文件的外部有fun main(...方法,那么编译成字节码后就是Java的Entrance类里有public sta ...
- Python 之自动获取公网IP
Python 之自动获取公网IP 2017年9月30日 文档下载:https://wenku.baidu.com/view/ff40aef7f021dd36a32d7375a417866fb84ac0 ...
- CxGrid鼠标移到更改颜色
CxGrid鼠标移到更改颜色 设置表单中TcxGrid1DBTableView的Styles属性,设置Selection procedure TForm1.cxGrid1DBTableView1Mou ...
- Android-Java静态代码块&局部代码块
静态代码块: 静态代码块什么时候执行,是由当前类被加载进内存的时候,什么时候当前类被加载进内存? 答:例如 描述好了Student对象,当 new Student(); 的时候,第一步:是把Stude ...
- 用XPath查找HTML节点或元素
更新版以后会在我的新博客更新,请您移步 https://blog.clso.fun/posts/2019-03-03/46.html 虽然JQ和JS都能很方便的查找包含了ID及类名的元素,但某些情况下 ...