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)和wait(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

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值