他们是LockSupport中的方法

  1. //暂停当前线程
  2. LockSupport.park();
  3. //恢复某个线程的运行,参数需要传递要恢复的线程是哪个
  4. LockSupport.unPark(Thread thread);

注意:unpark既可以在park之前调用,也可以在park之后调用;也就是说park先暂停了某个线程,可以通过unPark恢复,也可以在park暂停之前就先恢复某个线程;
正常情况下暂停一秒线程,两秒后恢复线程:

  1. //正常情况
  2. public static void main(String[] args) {
  3. try {
  4. Thread thread = new Thread(() -> {
  5. log.debug("start...");
  6. try {
  7. TimeUnit.SECONDS.sleep(1);
  8. log.debug("park...");
  9. LockSupport.park();
  10. log.debug("已经唤醒");
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }, "t1");
  15. thread.start();
  16. //两秒后唤醒
  17. TimeUnit.SECONDS.sleep(2);
  18. log.debug("--unpark");
  19. LockSupport.unpark(thread);
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. -----输出
  25. [t1] DEBUG com.example.myproject - start...
  26. [t1] DEBUG com.example.myproject - park...
  27. [main] DEBUG com.example.myproject --unpark
  28. [t1] DEBUG com.example.myproject- 已经唤醒

非正常情况暂停两秒线程,却在1秒的时候就恢复,也就是unpark在park之前调用

  1. //正常情况
  2. public static void main(String[] args) {
  3. try {
  4. Thread thread = new Thread(() -> {
  5. log.debug("start...");
  6. try {
  7. //这里改为暂停2秒
  8. TimeUnit.SECONDS.sleep(2);
  9. log.debug("park...");
  10. LockSupport.park();
  11. log.debug("已经唤醒");
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }, "t1");
  16. thread.start();
  17. //这里改为1秒后唤醒
  18. TimeUnit.SECONDS.sleep(1);
  19. log.debug("--unpark");
  20. LockSupport.unpark(thread);
  21. } catch (Exception e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. -----输出,这里的结果就是先唤醒,然后在执行的park
  26. [t1] DEBUG com.example.myproject - start...
  27. [main] DEBUG com.example.myproject --unpark
  28. [t1] DEBUG com.example.myproject - park...
  29. [t1] DEBUG com.example.myproject- 已经唤醒

与Object方法中的wait&notify区别

  • park & unprk是LockSupport的方法,而wait、notify是Object的方法;
  • wait、notify和notifyAll必须配合synchronize一起使用,而park,unpark不需要;
  • park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,因为unpark需要传递一个线程参数,所以unpark能【精确】的唤醒线程;而notify只能随机唤醒一个等待的线程,notifyAll是唤醒所有等待线程,就不是那么【精确】。
  • park & unprk 可以先unpark,在park,没有顺序,而wait & notify则必须先wait,才能notify,必须有顺序。