不使用Thread.join() 测试线程

先上代码:

  1. /**
  2. * Created by Zero on 2017/8/23.
  3. */
  4. public class TestJoin implements Runnable {
  5. public static int a = 0;
  6. @Override
  7. public void run() {
  8. for (int i = 0; i < 5; i++) {
  9. a = a + 1;
  10. }
  11. }
  12. public static void main(String[] args) throws InterruptedException {
  13. TestJoin j = new TestJoin();
  14. Thread thread = new Thread(j);
  15. thread.start();
  16. System.out.println(a);
  17. }
  18. }

以上示例会输出5吗?可能性不大,有可能永远输出为0,之前在线程池原理的那篇就提到过,线程的启动和销毁都需要时间,此处因为thread还没启动好,或者正在为它分配资源准备运行,就已经执行完输出了。

怎样才能确保每次都能输出5呢?现在有请我们的主角join方法闪亮登场,代码如下:

  1. /**
  2. * Created by apple on 2017/8/23.
  3. */
  4. public class TestJoin implements Runnable {
  5. public static int a = 0;
  6. @Override
  7. public void run() {
  8. for (int i = 0; i < 5; i++) {
  9. a = a + 1;
  10. }
  11. }
  12. public static void main(String[] args) throws InterruptedException {
  13. TestJoin j = new TestJoin();
  14. Thread thread = new Thread(j);
  15. thread.start();
  16. /**
  17. * 测试join方法的作用,与下面的threadAgain线程作对比。
  18. */
  19. thread.join();
  20. System.out.println(a);
  21. a = 0;
  22. Thread threadAgain = new Thread(j);
  23. threadAgain.start();
  24. System.out.println(a);
  25. }
  26. }

输出的结果将是5和0。

Thread.join()作用

Thread.join(),之前看资料的时候,有些人说可以理解成“将两个线程合并成一个线程”,我是觉得这样说是很不科学的,虽然这样通俗易懂,但这确实是两个不同的线程,只是在调用Thread.join()后,会先执行完Thread线程后再去执行当前线程,即上述的在主线程中执行到thread.join();后,先去执行thread,直到thread执行完后再去执行主线程。

测试Thread.join(long millis)

  1. /**
  2. * Created by apple on 2017/8/23.
  3. */
  4. public class TestJoin implements Runnable {
  5. public static int a = 0;
  6. @Override
  7. public void run() {
  8. for (int i = 0; i < 5; i++) {
  9. a = a + 1;
  10. try {
  11. Thread.sleep(1000);
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. }
  17. public static void main(String[] args) throws InterruptedException {
  18. TestJoin j = new TestJoin();
  19. Thread thread = new Thread(j);
  20. thread.start();
  21. /**
  22. * 测试join方法的作用
  23. */
  24. thread.join(3000);
  25. System.out.println("thread线程结果为:"+a);
  26. a = 0;
  27. Thread threadAgain = new Thread(j);
  28. threadAgain.start();
  29. System.out.println("threadAgain线程结果为:"+a);
  30. }
  31. }

输出:

  1. thread线程结果为:3
  2. threadAgain线程结果为:0

先上一段源码再来分析:

  1. /**
  2. * Waits at most {@code millis} milliseconds for this thread to
  3. * die. A timeout of {@code 0} means to wait forever.
  4. *
  5. * <p> This implementation uses a loop of {@code this.wait} calls
  6. * conditioned on {@code this.isAlive}. As a thread terminates the
  7. * {@code this.notifyAll} method is invoked. It is recommended that
  8. * applications not use {@code wait}, {@code notify}, or
  9. * {@code notifyAll} on {@code Thread} instances.
  10. *
  11. * @param millis
  12. * the time to wait in milliseconds
  13. *
  14. * @throws IllegalArgumentException
  15. * if the value of {@code millis} is negative
  16. *
  17. * @throws InterruptedException
  18. * if any thread has interrupted the current thread. The
  19. * <i>interrupted status</i> of the current thread is
  20. * cleared when this exception is thrown.
  21. */
  22. public final synchronized void join(long millis)
  23. throws InterruptedException {
  24. long base = System.currentTimeMillis();
  25. long now = 0;
  26. if (millis < 0) {
  27. throw new IllegalArgumentException("timeout value is negative");
  28. }
  29. if (millis == 0) {
  30. while (isAlive()) {
  31. wait(0);
  32. }
  33. } else {
  34. while (isAlive()) {
  35. long delay = millis - now;
  36. if (delay <= 0) {
  37. break;
  38. }
  39. wait(delay);
  40. now = System.currentTimeMillis() - base;
  41. }
  42. }
  43. }

源码爸爸说了,孩子,我给你millis这么长的时间,能不能完成任务那是你的事情了,能提前完成,咱就提前走下去,不能完成,过期不候,自己看着办吧。

默认情况下,Thread.join()即Thread.join(0),当为0的时候,那才叫真爱呢,线程会一直等下去,知道执行结束为止,才会继续朝下执行。

isAlive():用来测试线程是否处于活动状态,相当于 run 是否还在执行。

多线程:head first Thread.join()的更多相关文章

  1. 多线程进阶---Thread.join()/CountDownLatch.await() /CyclicBarrier.await()

    Thread.join() CountDownLatch.await() CyclicBarrier.await() 三者都是用来控制程序的"流动" 可以让程序"堵塞&q ...

  2. java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)

    本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...

  3. C#多线程详解(一) Thread.Join()的详解

    bicabo   C#多线程详解(一) Thread.Join()的详解 什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程 ...

  4. 多线程编程(一) - 关于C#中Thread.Join()

    Thread.Join()在MSDN中的解释很模糊:Blocks the calling thread until a thread terminates 有两个主要问题:1.什么是the calli ...

  5. C#多线程Thread.Join()的详解

    class TestThread { private static void FirstThreadFun() { ; i < ; i++) { Console.WriteLine(Thread ...

  6. 多线程--Thread.join方法

    在Thread类的Api中,Join的作用是让当前线程等待目标线程结束之后才继续执行. thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.  比如在线程B ...

  7. java 多线程 Thread.join子线程结束父线程再运行;join(long):等待超时毫秒数

    Join的使用 目的:当子线程运行结束后,父线程才能再继续运行 /** * @ClassName ThreadJoinExample * @projectName: object1 * @author ...

  8. C#中Thread.Join()的理解

    最近在项目中使用多线程,但是对多线程的一些用法和概念还有有些模棱两可,为了搞清楚查阅了一写资料,写下这篇日志加深理解吧. Thread.Join()在MSDN中的解释很模糊:Blocks the ca ...

  9. Java Thread.join的作用和原理

    很多人对Thread.join的作用以及实现了解得很少,毕竟这个api我们很少使用.这篇文章仍然会结合使用及原理进行深度分析 内容导航 Thread.join的作用 Thread.join的实现原理 ...

随机推荐

  1. 200行的Node爬虫花了半天的时间把网易云上的30万首歌曲信息都抓取回来了

    早两天在网易云听歌看评论的时候,突然想把网易云上所有歌曲都抓取下来然后按照评论数进行一次排名,把评论数超过10万的歌曲都听一次,于是便有了这个项目. 因为只是一个小前端,所以使用了Node来写这个爬虫 ...

  2. 一款轻量级前端框架Avalon.Js

    avalon2是一款基于虚拟DOM与属性劫持的 迷你. 易用. 高性能 的 前端MVVM框架, 拥有超优秀的兼容性, 支持移动开发, 后端渲染, WEB Component式组件开发, 无需编译, 开 ...

  3. Servlet3.1上传图片示例

    一.前端JSP页面 <%@page pageEncoding="UTF-8"%><!DOCTYPE html><html><head> ...

  4. TP-Link路由器的设置向导

    TP-Link路由器的设置向导.. 一.准备工作: 1.首先是路由器的安装,主要是将路由器电源接上,并通电,然后就是网线的连接.如果是拨号上网用户,请将猫引出的网线插入到TP-Link路由器最特别的一 ...

  5. 聊聊GIS中那些坐标系

    从第一次上地图学的课开始,对GIS最基本的地图坐标系统就很迷.也难怪,我那时候并不是GIS专业的学生,仅仅是一门开卷考试的专业选修课,就没怎么在意. 等我真正接触到了各种空间数据产品,我才知道万里长征 ...

  6. SpringMVC(三)-- 视图和视图解析器、数据格式化标签、数据类型转换、SpringMVC处理JSON数据、文件上传

    1.视图和视图解析器 请求处理方法执行完成后,最终返回一个 ModelAndView 对象 对于那些返回 String,View 或 ModeMap 等类型的处理方法,SpringMVC 也会在内部将 ...

  7. 最长单词(一星级题目) 本来是很简单的,其实就是加个flag

    随机了一个题目: 给一个词典,找出其中所有最长的单词. 这道题对于初学者还是很有用的,毕竟用的逻辑是比较复杂的 样例 在词典 { "dog", "google" ...

  8. ThreadLocal类分析

    首先试想一个场景: 多个线程都要访问数据库,先要获得一个Connection,然后执行一些操作.为了线程安全,如果用synchronized锁定一个Connection对象,那么任何时候,都只有一个线 ...

  9. SQL Server内存

    背景 最近一个客户找到我说是所有的SQL Server 服务器的内存都被用光了,然后截图给我看了一台服务器的任务管理器.如图 这里要说明一下任务管理器不会完整的告诉真的内存或者CPU的使用情况,也就是 ...

  10. python环境搭建和打包

    安装: python是有两个版本的一个是2.x,一个是3.x,这两个版本是不兼容的所有请使用前看准版本.下面我们主要说3.5版本. Mac:https://www.python.org/ftp/pyt ...