文章目录
- 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