【并发】3、LockSupport阻塞与唤醒,相较与wait和notify
2018-03-04 13:52
465 查看
我们可以使用wait和notify分别对象线程进行阻塞或者唤醒,但是我们也可以使用LockSupport实现一样的功能,并且在实际使用的时候,个人感觉LockSupport会更加顺手
范例1,wait与notify
运行结果:
范例2,locksupport
效果展示:
两者相比我们就会发现,
1、locksupport不需要先进入对应的同步锁,也就是synchronize获取当前锁,然后才能使用wait进行释放
2、locksupport不局限在本线程中,更感觉是跳脱在线程外,对线程进行操控,不想synchronize中的notify,在没有退出同步代码块之前,这个锁实际上还是当前线程占用的,不管是否执行了notify
只有在退出了同步代码块,这个锁才会真正的被释放
范例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
只有在退出了同步代码块,这个锁才会真正的被释放
相关文章推荐
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
- java并发包中的Condition和Lock 取代Synchronized、wait、notify/notifyAll实现线程的同步与互斥
- AQS(三):阻塞、唤醒:LockSupport (r)
- Java可阻塞队列的两种实现方式 (传统wait/notify和jdk1.5以后的lock)
- AQS阻塞唤醒工具LockSupport
- AQS阻塞唤醒工具LockSupport
- 并发编程复习(六):使用wait和notify模拟阻塞队列
- 阻塞和唤醒线程——LockSupport功能简介及原理浅析
- wait() 一定需要notify()唤醒吗?
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
- Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
- Java-线程$等待唤醒机制(wait,notify)
- java线程通讯——使用Lock和Condition代替synchronized 和 wait, notify notifyAll()
- 阻塞队列(CountDownLatch代替notify+wait解决wait释放锁,notify不释放锁问题)
- 使用Lock,wait/notify,Semaphore三种方式实现多线程通信
- [置顶] java并发编程—— 六 进程协作:阻塞队列\wait() notify()\ Condition
- Lock的lock/unlock, condition的await/singal 和 Object的wait/notify 的区别 - 永远是 ...