并发编程 - LockSupport 应用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发编程 - LockSupport 应用相关的知识,希望对你有一定的参考价值。


文章目录

  • ​​1. LockSupport方法介绍​​
  • ​​2. wait/notify 错误用法​​
  • ​​3. wait/notify 正确用法​​
  • ​​4. LockSupport 用法​​
  • ​​5. LockSupport 对比 Object 的 wait/notify 优势​​
  • ​​6. Reference​​

1. LockSupport方法介绍

  • ​阻塞线程​
  • void park(): 阻塞当前线程,如果调用unpark方法或者当前线程被中断,从能从park()方法中返回
  • void park(Object blocker): 功能同方法1,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
  • void parkNanos(long nanos): 阻塞当前线程,最长不超过nanos纳秒,增加了超时返回的特性;
  • void parkNanos(Object blocker, long nanos): 功能同方法3,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
  • void parkUntil(long deadline): 阻塞当前线程,知道deadline;
  • void parkUntil(Object blocker, long deadline): 功能同方法5,入参增加一个Object对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查;
  • ​唤醒线程​
  • void unpark(Thread thread): 唤醒处于阻塞状态的指定线程

 

2. wait/notify 错误用法

public class WaitApp 

public static void main(String[] args) throws InterruptedException
final Object object = new Object();

Thread thread = new Thread(() ->
int sum = 0;
for (int i = 0; i < 10; i++)
sum++;


try
object.wait();
catch (InterruptedException e)
e.printStackTrace();


System.out.println("sum: " + sum);
);

thread.start();
// 睡眠 1 秒, 保证线程 thread 完成计算, 阻塞在 wait 方法
Thread.sleep(1000);
object.notify();


 
​​​程序运行结果, 将报错​

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at com.locksupport.WaitApp.lambda$main$0(WaitApp.java:18)
at java.lang.Thread.run(Thread.java:748)

 

3. wait/notify 正确用法

public class WaitApp 

public static void main(String[] args) throws InterruptedException
final Object object = new Object();

Thread thread = new Thread(() ->
int sum = 0;
for (int i = 0; i < 10; i++)
sum += i;


try
System.out.println("ready to wait thread.");
// wait 方法只能在同步代码块中调用
synchronized (object)
object.wait();

catch (InterruptedException e)
e.printStackTrace();


System.out.println("sum: " + sum);
);

System.out.println("ready to start thread...");
thread.start();

System.out.println("ready to sleep...");
// 睡眠 3 秒, 保证线程 thread 完成计算, 阻塞在 wait 方法
// 保证 wait 方法先于 notify 方法执行
Thread.sleep(3000);

System.out.println("ready to notify thread.");
// notify 方法只能在同步代码块中调用
synchronized (object)
object.notify();



如果注释掉 ​​Thread.sleep(3000);​​​ 代码, 那么会出现这种情况: ​​主线程调用完 notify() 方法后, 线程 thread 才进入 wait() 方法, 此时线程 thread 会一直阻塞着, 从而导致整个程序无法退出。​

注意: ​​wait和notify/notifyAll方法只能在同步代码块里用​

​程序运行结果​

ready to start thread...
ready to sleep...
ready to wait thread.

// sleep...

ready to notify thread.
sum: 499500

 

4. LockSupport 用法

public class LockSupportApp 

public static void main(String[] args) throws InterruptedException

Thread thread = new Thread(() ->
int sum = 0;

for (int i = 0; i < 10; i++)
sum += i;

System.out.println("ready to park thread.");
LockSupport.park();

System.out.println("sum:" + sum);
);

System.out.println("ready to start thread...");
thread.start();

// 此处 main 主线程 不需要休眠

System.out.println("ready to unpark thread.");
LockSupport.unpark(thread);


 
​​​程序运行结果​

ready to start thread...
ready to unpark thread.
ready to park thread.
sum:499500

 

5. LockSupport 对比 Object 的 wait/notify 优势



 

6. Reference


以上是关于并发编程 - LockSupport 应用的主要内容,如果未能解决你的问题,请参考以下文章

并发编程系列之掌握LockSupport的用法

java并发编程之LockSupport

Java Review - 并发编程_LockSupport

Java Review - 并发编程_LockSupport

深入浅出Java并发编程指南「原理分析篇」从底层分析LockSupport原理机制体系

Java并发编程原理 - Unsafe && LockSupport类及AQS同步器的设计