1. sleep

  • 主线程的 sleep 不会影响 子线程;
  • 线程在休眠时不会释放锁;

    1. static SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
    2. public static void testSleep(){
    3. class Thread1 implements Runnable{
    4. @Override
    5. public void run(){
    6. synchronized (sdf) {
    7. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread1 start");
    8. try {
    9. Thread.sleep(3000);
    10. } catch (InterruptedException e) {
    11. e.printStackTrace();
    12. }
    13. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread1 end");
    14. }
    15. }
    16. }
    17. class Thread2 implements Runnable{
    18. @Override
    19. public void run(){
    20. synchronized (sdf) {
    21. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread2 start");
    22. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread2 end");
    23. }
    24. }
    25. }
    26. new Thread(new Thread1()).start();
    27. try {
    28. Thread.sleep(2000);
    29. } catch (InterruptedException e) {
    30. e.printStackTrace();
    31. }
    32. new Thread(new Thread2()).start();
    33. // 主线程 sleep + 子线程 sleep + 无锁
    34. /** outPut
    35. * 09:13 : main start
    36. * 09:13 : thread1 start
    37. * 09:15 : main end
    38. * 09:15 : thread2 start
    39. * 09:15 : thread2 end
    40. * 09:16 : thread1 end
    41. */
    42. // 给子线程加锁 synchronized
    43. /** output
    44. * 22:06 : main start
    45. * 22:06 : thread1 start
    46. * 22:08 : main end
    47. * 22:09 : thread1 end
    48. * 22:09 : thread2 start
    49. * 22:09 : thread2 end
    50. */
    51. }

    2. wait

  • wait 后,锁会被释放,若不唤醒,线程将一直阻塞;

    1. public static void testWait(){
    2. class Thread1 implements Runnable{
    3. @Override
    4. public void run(){
    5. synchronized (sdf) {
    6. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread1 start");
    7. try {
    8. Thread.sleep(3000);
    9. } catch (InterruptedException e) {
    10. e.printStackTrace();
    11. }
    12. try {
    13. System.out.println(sdf.format(System.currentTimeMillis()) + " : begin to wait");
    14. sdf.wait();
    15. System.out.println(sdf.format(System.currentTimeMillis()) + " : end waiting, then restart");
    16. } catch (InterruptedException e) {
    17. e.printStackTrace();
    18. }
    19. try {
    20. Thread.sleep(4000);
    21. } catch (InterruptedException e) {
    22. e.printStackTrace();
    23. }
    24. sdf.notify(); //让出锁,唤醒 Thread2 继续运行
    25. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread1 end");
    26. }
    27. }
    28. }
    29. class Thread2 implements Runnable{
    30. @Override
    31. public void run(){
    32. synchronized (sdf) {
    33. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread2 start");
    34. try {
    35. // Thread.sleep(5000);
    36. sdf.wait();
    37. } catch (InterruptedException e) {
    38. e.printStackTrace();
    39. }
    40. sdf.notify();//让出锁,唤醒 Thread1 继续运行
    41. System.out.println(sdf.format(System.currentTimeMillis()) + " : thread2 end");
    42. }
    43. }
    44. }
    45. new Thread(new Thread1()).start();
    46. try {
    47. Thread.sleep(2000);
    48. } catch (InterruptedException e) {
    49. e.printStackTrace();
    50. }
    51. new Thread(new Thread2()).start();
    52. // 无 notify()
    53. /** output
    54. * 30:09 : main start
    55. * 30:09 : thread1 start
    56. * 30:11 : main end
    57. * 30:12 : begin to wait
    58. * 30:12 : thread2 start
    59. * 30:17 : thread2 end
    60. * ............ 运行无终止
    61. */
    62. // notify Thread.sleep(5000);
    63. /** output
    64. * 35:52 : main start
    65. * 35:52 : thread1 start
    66. * 35:54 : main end
    67. * 35:55 : begin to wait
    68. * 35:55 : thread2 start
    69. * 36:00 : thread2 end
    70. * 36:00 : end waiting, then restart
    71. * 36:04 : thread1 end
    72. */
    73. // notify sdf.wait()
    74. /** output
    75. * 13:05 : main start
    76. * 13:05 : thread1 start
    77. * 13:07 : main end
    78. * 13:08 : begin to wait
    79. * 13:08 : thread2 start
    80. * 13:08 : end waiting, then restart
    81. * 13:12 : thread1 end
    82. * 13:12 : thread2 end
    83. */
    84. }

    3. join

  • 在被 join 的线程执行完之前,主线程处于等待状态;

    public static void testJoin1(){
       class Thread1 implements Runnable{
           @Override
           public void run(){
               System.out.println(sdf.format(System.currentTimeMillis()) + " : thread1 start");
               try {
                   Thread.sleep(3000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println(sdf.format(System.currentTimeMillis()) + " : thread1 end");
           }
       }
       Thread thread = new Thread(new Thread1());
       thread.start();
       try {
           thread.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       // no join
       /** output
        * 28:00 : main start
        * 28:00 : main end
        * 28:00 : thread1 start
        * 28:03 : thread1 end
        */
       // add join
       /** output
        * 28:51 : main start
        * 28:51 : thread1 start
        * 28:54 : thread1 end
        * 28:54 : main end
        */
    }
    public static void testJoin2(){
       // 在被 join 的线程执行前,两个线程交替进行,而主线程处于等待状态,直到被 join 的线程执行完毕,主线程继续执行;
       class JoinThread extends Thread{
           public JoinThread(String name){
               super(name);
           }
           @Override
           public void run(){
               for (int i = 0; i < 10; i++) {
                   System.out.println(getName() + " : " + i);
               }
           }
       }
       new JoinThread("新线程").start();
       for (int i = 0; i < 10; i++) {
           System.out.println(Thread.currentThread().getName() + ":" + i);
           if (i == 3) {
               JoinThread thread = new JoinThread("被 join 的线程");
               thread.start();
               try{
                   thread.join();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
    
           }
       }
       /** output
        * 30:36 : main start
        * main:0
        * main:1
        * main:2
        * main:3
        * 新线程 : 0
        * 新线程 : 1
        * 新线程 : 2
        * 新线程 : 3
        * 新线程 : 4
        * 新线程 : 5
        * 新线程 : 6
        * 被 join 的线程 : 0
        * 新线程 : 7
        * 新线程 : 8
        * 新线程 : 9
        * 被 join 的线程 : 1
        * 被 join 的线程 : 2
        * 被 join 的线程 : 3
        * 被 join 的线程 : 4
        * 被 join 的线程 : 5
        * 被 join 的线程 : 6
        * 被 join 的线程 : 7
        * 被 join 的线程 : 8
        * 被 join 的线程 : 9
        * main:4
        * main:5
        * main:6
        * main:7
        * main:8
        * main:9
        * 30:36 : main end
        */
    }
    

    4. yield

  • 暂时让渡 cpu 调度权,再参与抢夺;
      public static void testYield(){
          class Thread1 implements Runnable{
              @Override
              public void run(){
                  for (int i = 0; i < 5; i++) {
                      System.out.println(Thread.currentThread().getName() + " : " + i);
                      if (i == 2) {
                          Thread.yield();
                      }
                  }
              }
          }
          class Thread2 implements Runnable{
              @Override
              public void run(){
                  for (int i = 0; i < 5; i++) {
                      System.out.println(Thread.currentThread().getName() + " : " + i);
                      if (i == 3) {
                          Thread.yield();
                      }
                  }
              }
          }
          Thread thread1 = new Thread(new Thread1());
          Thread thread2 = new Thread(new Thread2());
          thread1.start();
          thread2.start();
          /** output
           * 45:03 : main start
           * 45:03 : main end
           * Thread-0 : 0
           * Thread-1 : 0
           * Thread-0 : 1
           * Thread-1 : 1
           * Thread-1 : 2
           * Thread-0 : 2
           * Thread-1 : 3
           * Thread-0 : 3
           * Thread-1 : 4
           * Thread-0 : 4
           */
      }