【并发】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.11.04 洛谷P2679 子串(线性dp)
传送门 为什么前几年的noipnoipnoip总是出这种送分题啊? 这个直接线性dpdpdp不就完了吗? f[i][j][k][0/1]f[i][j][k][0/1]f[i][j][k][0/1]表示 ...
- 开启Greenplum DataBase报错:could not bind IPv4 socket: Address already in use
在运行gpstart时无法开启服务,查看日志看到下图所示错误: 查看日志错误大概是端口已被占用,所以无法重启. 解决方法: (1)利用ipcs查看数据库占用的共享内存.(如下图所示) (2)查看数据库 ...
- python模块:pickle
"""Create portable serialized representations of Python objects. See module copyreg f ...
- Oracle数据库使用mybatis的时候,实体类日期为Date类型,mybatis里面定义的是Date类型,插入的时候,时分秒全部是12:00:00问题
实体类中日期定义的是Date类型的,没毛病: 我在mybatis里面定义的是Date类型的,进行测试的时候发现,数据库插入的日期的时分秒全部都是一样的,都是12:00:00,很郁闷: 后来把mybat ...
- Redis-环境搭建
Redis官方不提供Windows版,不过微软开源组织提供了Windows版本的Redis,此处将安装Windows版的Reids,供学习使用. 1.下载Windows版Redis安装包: 安装包地址 ...
- 深入理解,函数声明、函数表达式、匿名函数、立即执行函数、window.onload的区别.
一.函数声明.函数表达式.匿名函数1.函数声明:function fnName () {…};使用function关键字声明一个函数,再指定一个函数名,叫函数声明. 2.函数表达式 var fnNam ...
- 同时安装python2.7和python3.5
同时安装python2.7和python3.5,并配置sublime ctrl+B选择运行python版本 安装python 首先是安装两个版本的python,并配置相应的环境变量 1.在下载安装好P ...
- Linux 下socket通信终极指南(附TCP、UDP完整代码)
linux下用socket通信,有TCP.UDP两种协议,网上的很多教程把两个混在了一起,或者只讲其中一种.现在我把自己这两天研究的成果汇总下来,写了一个完整的,适合初学者参考,也方便自己以后查阅. ...
- axios基础
一.安装 <script src="https://unpkg.com/axios/dist/axios.min.js"></script> npm ins ...
- Poj2296
题意:给定n个点,然后在每个点在一个正方形的上边或者下边的中点,并且所有的正方形等大且不能重叠.求正方形最大的边长是多少. 思路:很明显的二分边长+判定.不过判定要用到2-sat,算是2-sat的入门 ...