我们可以使用wait和notify分别对象线程进行阻塞或者唤醒,但是我们也可以使用LockSupport实现一样的功能,并且在实际使用的时候,个人感觉LockSupport会更加顺手

范例1,wait与notify

  1. class WaitTest1 {
  2.  
  3. static class ThreadA extends Thread {
  4. public ThreadA(String name) {
  5. super(name);
  6. }
  7.  
  8. @Override
  9. public void run() {
  10. synchronized (this) {
  11. System.out.println(Thread.currentThread().getName() + " wakup others");
  12. this.notify(); // 唤醒当前线程对象
  13. for (int i = 0; i < 10; ++i) {
  14. try {
  15. Thread.sleep(1000);
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. System.out.println("唤醒当前线程对象之后" + i);
  20. }
  21. }
  22.  
  23. for (int i = 0; i < 10; ++i) {
  24. System.out.println("唤醒当前线程对象,释放锁之后前" + i);
  25. try {
  26. Thread.sleep(1000);
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. System.out.println("唤醒当前线程对象,释放锁之后" + i);
  31. }
  32.  
  33. }
  34. }
  35.  
  36. public void mian1() {
  37. ThreadA ta = new ThreadA("ta");
  38.  
  39. //因为wait需释放锁,所以必须在synchronized中使用(没有锁定则么可以释放?没有锁时使用会抛出IllegalMonitorStateException(正在等待的对象没有锁))
  40. synchronized (ta) {
  41. try {
  42.  
  43. System.out.println(Thread.currentThread().getName() + " start ta");
  44. ta.start();
  45.  
  46. System.out.println(Thread.currentThread().getName() + " block");
  47. // 主线程等待,释放当前线程锁
  48. ta.wait();
  49.  
  50. System.out.println(Thread.currentThread().getName() + " continue");
  51.  
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. }
  57. }

运行结果:

范例2,locksupport

  1. class LockSupportTest1 {
  2. private static Thread mainThread;
  3.  
  4. static class ThreadA extends Thread {
  5. public ThreadA(String name) {
  6. super(name);
  7. }
  8.  
  9. @Override
  10. public void run() {
  11. synchronized (this) {
  12. System.out.println(Thread.currentThread().getName() + " wakup others");
  13. // this.notify(); // 唤醒当前线程对象
  14. LockSupport.unpark(mainThread); //this,这里就不能使用this了,如果这里使用this,那么其实并没有释放这个对象的锁,释放的对象是ta的锁,那就会造成死锁
  15. for (int i = 0; i < 10; ++i) {
  16. try {
  17. Thread.sleep(1000);
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. System.out.println("唤醒当前线程对象之后" + i);
  22. }
  23. }
  24.  
  25. for (int i = 0; i < 10; ++i) {
  26. System.out.println("唤醒当前线程对象,释放锁之后前" + i);
  27. try {
  28. Thread.sleep(1000);
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. System.out.println("唤醒当前线程对象,释放锁之后" + i);
  33. }
  34.  
  35. }
  36. }
  37.  
  38. public void main1() {
  39. ThreadA ta = new ThreadA("LockSupportTest1");
  40. //获取当前主线程对象
  41. mainThread = Thread.currentThread();
  42.  
  43. System.out.println(Thread.currentThread().getName() + " start ta");
  44. ta.start();
  45.  
  46. System.out.println(Thread.currentThread().getName()+" block");
  47.  
  48. //对主线程进行阻塞
  49. LockSupport.park(mainThread);
  50.  
  51. System.out.println(Thread.currentThread().getName()+" continue");
  52.  
  53. }
  54.  
  55. }

效果展示:

两者相比我们就会发现,

1、locksupport不需要先进入对应的同步锁,也就是synchronize获取当前锁,然后才能使用wait进行释放

2、locksupport不局限在本线程中,更感觉是跳脱在线程外,对线程进行操控,不想synchronize中的notify,在没有退出同步代码块之前,这个锁实际上还是当前线程占用的,不管是否执行了notify

  只有在退出了同步代码块,这个锁才会真正的被释放

【并发】3、LockSupport阻塞与唤醒,相较与wait和notify的更多相关文章

  1. 阻塞和唤醒线程——LockSupport功能简介及原理浅析

    目录 1.LockSupport功能简介 1.1 使用wait,notify阻塞唤醒线程 1.2 使用LockSupport阻塞唤醒线程 2. LockSupport的其他特色 2.1 可以先唤醒线程 ...

  2. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  3. Java并发框架——AQS之阻塞与唤醒

    根据前面的线程阻塞与唤醒小节知道,目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合.wait与notify组合.park与unpark组合.其中suspend与r ...

  4. 多线程之Java线程阻塞与唤醒

    线程的阻塞和唤醒在多线程并发过程中是一个关键点,当线程数量达到很大的数量级时,并发可能带来很多隐蔽的问题.如何正确暂停一个线程,暂停后又如何在一个要求的时间点恢复,这些都需要仔细考虑的细节.在Java ...

  5. 从JDK源码角度看线程的阻塞和唤醒

    目前在Java语言层面能实现阻塞唤醒的方式一共有三种:suspend与resume组合.wait与notify组合.park与unpark组合.其中suspend与resume因为存在无法解决的竟态问 ...

  6. 深入理解Object提供的阻塞和唤醒API

    深入理解Object提供的阻塞和唤醒API 前提 前段时间花了大量时间去研读JUC中同步器AbstractQueuedSynchronizer的源码实现,再结合很久之前看过的一篇关于Object提供的 ...

  7. J.U.C之AQS:阻塞和唤醒线程

    此篇博客所有源码均来自JDK 1.8 在线程获取同步状态时如果获取失败,则加入CLH同步队列,通过通过自旋的方式不断获取同步状态,但是在自旋的过程中则需要判断当前线程是否需要阻塞,其主要方法在acqu ...

  8. Java并发编程:阻塞队列(转载)

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...

  9. 【转】Java并发编程:阻塞队列

    在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程 ...

随机推荐

  1. 2018.11.30 spoj220 Relevant Phrases of Annihilation(后缀数组+二分答案)

    传送门 代码: 先用特殊字符把所有字符串连接在一起. 然后二分答案将sasasa数组分组. 讨论是否存在一个组满足组内对于每一个字符串都存在两段不相交字串满足条件. #include<bits/ ...

  2. 2018.11.02 洛谷P3952 时间复杂度(模拟)

    传送门 惊叹考场dubuffdubuffdubuff. 这题还没有梭哈难啊233. 直接按照题意模拟就行了. 代码: #include<bits/stdc++.h> using names ...

  3. 2018.10.24 bzoj2064: 分裂(状压dp)

    传送门 状压dp好题. 考虑对于两个给出的集合. 如果没有两个元素和相等的子集,那么只能全部拼起来之后再拆开,一共需要n1+n2−2n1+n2-2n1+n2−2. 如果有呢? 那么对于没有的就是子问题 ...

  4. MySQL/Oracle视图的创建与使用

    1.什么是视图? 视图是一个虚拟的表,是一个表中的数据经过某种筛选后的显示方式,视图由一个预定义的查询select语句组成.   2.视图的特点. 视图中的数据并不属于视图本身,而是属于基本的表,对视 ...

  5. ubuntu上安装win7系统(64位的)

    http://www.linuxidc.com/Linux/2012-11/74195.htm deb文件在ubuntu上直接用dpkg -i xxx.deb 如果虚拟机上只显示32位,则可能是cpu ...

  6. UVa 10163 Storage Keepers (二分 + DP)

    题意:有n个仓库,m个管理员,每个管理员有一个能力值P,每个仓库只能由一个管理员看管,但是每个管理员可以看管k个仓库(但是这个仓库分配到的安全值只有p/k,k=0,1,...),雇用的管理员的工资即为 ...

  7. ThinkPHP3.2.3:使用模块映射隐藏后台真实访问地址

    例如:项目应用目录/Application下模块如下,默认后台模块为Admin 现在需要修改后台模块的访问地址,以防被别有用心的人很容易就猜到,然后各种乱搞... (在公共配置文件/Applicati ...

  8. 【慕课网实战】Spark Streaming实时流处理项目实战笔记八之铭文升级版

    铭文一级: Spark Streaming is an extension of the core Spark API that enables scalable, high-throughput, ...

  9. 11-border(边框)

    边框 border:边框的意思,描述盒子的边框 边框有三个要素: 粗细 线性样式 颜色 border: solid 如果颜色不写,默认是黑色.如果粗细不写,不显示边框.如果只写线性样式,默认的有上下左 ...

  10. (转)类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET BCL里有哪些是类(结构),为什么它们不是结构(类)?在自定义类型时,您如何选择是类还是结构?

    转自:http://blog.csdn.net/lingxyd_0/article/details/8695747 类(class)和结构(struct)的区别是什么?它们对性能有影响吗?.NET B ...