首页 > 编程语言 >并发编程 - LockSupport 应用

并发编程 - LockSupport 应用

时间:2022-12-03 10:07:00浏览次数:65  
标签:Object thread sum 编程 LockSupport 并发 线程 notify wait


文章目录

  • ​​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


标签:Object,thread,sum,编程,LockSupport,并发,线程,notify,wait
From: https://blog.51cto.com/u_15891990/5908453

相关文章