Join() 用法简介

 

Join()

      Join使用方法:

主线程创建并启动子线程,如果子线程中要进行大量的耗时计算,主线程往往早于子线程结束,如果主线程想等待子线程执行完成后再结束,比如需要获得子线程处理的数据,就需要用到join()。

        

         验证代码:


 


public class MyThread extends Thread {

   @Override
   public void run() {
      try {
         int secondValue = (int) (Math.random() * 10000);
         System.out.println(secondValue);
         Thread.sleep(secondValue);
      } catch (InterruptedException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }

}



import extthread.MyThread;



public class Test {



   public static void main(String[] args) {

      try {

         MyThread threadTest = new MyThread();

         threadTest.start();

         threadTest.join();



         System.out.println("1111");

      } catch (InterruptedException e) {

         e.printStackTrace();

      }

   }



}

运行结果:

5861

1111

 

Join与异常:

         主线程中,调用两个子线程,当一个线程遇到interrupt(),则该线程终端,抛出异常,但并不影响另一个子线程和主线程。

 

验证代码:

 

public class ThreadA extends Thread {

   @Override

   public void run() {

      for (int i = 0; i < Integer.MAX_VALUE; i++) {

         String newString = new String();

         Math.random();

      }

   }

}


public class ThreadB extends Thread {



   @Override

   public void run() {

      try {

         ThreadA a = new ThreadA();

         a.start();

         a.join();



         System.out.println("B run over");

      } catch (InterruptedException e) {

         System.out.println("B interrupt");

         e.printStackTrace();

      }

   }



}



public class ThreadC extends Thread {



   private ThreadB threadB;



   public ThreadC(ThreadB threadB) {

      super();

      this.threadB = threadB;

   }



   @Override

   public void run() {

      threadB.interrupt();

      System.out.println("C run ");

   }



}


import extthread.ThreadB;

import extthread.ThreadC;



public class Run {



   public static void main(String[] args) {



      try {

         ThreadB b = new ThreadB();

         b.start();



         Thread.sleep(500);



         ThreadC c = new ThreadC(b);

         c.start();



         System.out.println("main run over");

      } catch (InterruptedException e) {

         e.printStackTrace();

      }

   }



}

 

 

运行结果:

java.lang.InterruptedException

         at java.lang.Object.wait(Native Method)

         at java.lang.Thread.join(Thread.java:1249)

         at java.lang.Thread.join(Thread.java:1323)

         at extthread.ThreadB.run(ThreadB.java:10)

main run over

C run

B interrupt

 

 

Join(long)和sleep(long)的区别:

Join(long)和wait(long)都是设定时间等待线程。但是其中区别是什么呢?

首先看一下Join(long)源码:

      
  public final synchronized void join(long millis)

throws InterruptedException {

    long base = System.currentTimeMillis();

    long now = 0;



    if (millis < 0) {

        throw new IllegalArgumentException("timeout value is negative");

    }



    if (millis == 0) {

        while (isAlive()) {

            wait(0);

        }

    } else {

        while (isAlive()) {

            long delay = millis - now;

            if (delay <= 0) {

                break;

            }

            wait(delay);

            now = System.currentTimeMillis() - base;

        }

    }

}

 

json是通过wait(long)来实现,wait(long)会释放锁。

 

join(long)和sleep(long)的区别:

         join(long):当前线程的锁被释放,其他现场可以调用此线程的同步方法。

         Sleep(long):不释放锁。

         因此join和sleep的主要却别在于对同步的处理上。

 

具体看代码:

public class ThreadA extends Thread {



   private ThreadB b;



   public ThreadA(ThreadB b) {

      super();

      this.b = b;

   }



   @Override

   public void run() {

      try {

         synchronized (b){

            b.start();

            Thread.sleep(6000);

         }

            // Thread.sleep()不释放锁

      } catch (InterruptedException e) {

         e.printStackTrace();

      }

   }

}


public class ThreadB extends Thread {



   @Override

   public void run() {

      try {

         System.out.println("   b run begin timer="

               + System.currentTimeMillis());

         Thread.sleep(5000);

         System.out.println("   b run   end timer="

               + System.currentTimeMillis());

      } catch (InterruptedException e) {

         e.printStackTrace();

      }

   }



   synchronized public void bService() {

      System.out.println("打印了bService timer=" + System.currentTimeMillis());

   }



}




public class ThreadC extends Thread {



   private ThreadB threadB;



   public ThreadC(ThreadB threadB) {

      super();

      this.threadB = threadB;

   }



   @Override

   public void run() {

      threadB.bService();

   }





}


public class Run {



   public static void main(String[] args) {



      try {

         ThreadB b = new ThreadB();



         ThreadA a = new ThreadA(b);

         a.start();



         Thread.sleep(1000);



         ThreadC c = new ThreadC(b);

         c.start();

      } catch (InterruptedException e) {

         e.printStackTrace();

      }

   }



}

 

运行结果:验证sleep不释放锁

   b run begin timer=1535027906244

         (间隔5s,6s后释放锁)

   b run   end timer=1535027911245

打印了bService timer=1535027912244

 

将ThreadA 中的Thread.sleep(6000)修改为b.join(6000)。

public class ThreadA extends Thread {



   private ThreadB b;



   public ThreadA(ThreadB b) {

      super();

      this.b = b;

   }



   @Override

   public void run() {

      try {

         synchronized (b){

            b.start();

            b.join(6000);

         }

            // Thread.sleep()不释放锁

      } catch (InterruptedException e) {

         e.printStackTrace();

      }

   }

}

 

运行结果:  

b run begin timer=1535028336151

间隔1s

打印了bService timer=1535028337153

   b run   end timer=1535028341151

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/u012133048/article/details/81987970