百度了一下,终于明白了。这个解释最简单:
前提:join()方法肯定是被某个线程调用的。
 
A线程正在执行,突然执行的时候碰到了B.join(), 那么,A线程就必须要等到B线程执行完之后才能执行。
注意理解,是在A线程运行中,遇到了B.join().
MyTthread d = new MyThread();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t1.join();
t2.start();
 
这个是main线程运行的时候碰到了t1.join, 那么主线程就必须要等到t1线程执行完了之后,才能继续执行主线程。
 
至于,t1与t2线程,二者还是竞争关系。这个可以通过代码简单去验证:

package thread;

public class ThreadTest{
public static void main(String[] args) throws InterruptedException {
MyThread d1 = new MyThread("t1",2000);
MyThread d2 = new MyThread("t2", 2000);
Thread t1 = new Thread(d1);
Thread t2 = new Thread(d2); t1.start();
t2.start();
t1.join(); for(int i = 0; i < 50; i++){
System.out.println("Main:-->" + i);
}
}
} class MyThread extends Thread{
private String threadName;
private int times; public MyThread(String threadName, int times){
this.threadName = threadName;
this.times = times;
}
public void run(){
for(int i = 0 ; i < times; i++){
System.out.println(threadName + ":-->" + i);
}
}
}
这个的结果,main线程执行到t1.start(), t1线程启动后继续执行,当main线程执行到t1.join()时,main线程开始等待t1执行完成,完成之后,main线程继续执行,执行到t2.start()时,t2线程才开始启动。
如果10-12行换一下顺序:
t1.start();
t2.start();
t1.join();
那么,应该是t1线程和t2线程交叉执行,当执行到t1.join()时,main线程等待t1执行完成,但是t1和t2依然是竞争关系,等t1执行完成之后,main线程会开始执行,如果t2这个时候还没有完成,则t2又会和main线程交叉执行。
 
这个测试呢,只需要在MyThread d1 = new MyThread("t1",2000);时,通过控制t1和t2线程的打印此时来控制存活时间就可以了。比如t1与t2都比较大,那么看看最后一段是不是t1和t2交叉执行的,或者t1在t2后执行的,这样就能说明t1.join()对于t2是没有任何影响的。
 
一般,如果t1线程有一些耗费时间的处理,那么t1.join()就会保证等t1执行完成之前,main线程还存活者,main就相当于一个守护线程。 可能t1的处理结果正是main线程处理时需要的。
 
有些人理解成,将两个线程合并成一个,也很好理解。这里将t1与主线程合并成一个线程,t1继续与t2竞争执行。t1线程则是顺序执行的。t1部分完成之后,main部分开始执行。
 
也可以这么理解,t1.join相对于main来说,加一一把锁,控制了t1与main线程之间的同步。

Thread.join简单介绍的更多相关文章

  1. SQL Join简单介绍

    前沿 Join是关系型数据库系统的重要操作之一,SQL Server中包含的常用Join:内联接.外联接和交叉联接等. 如果我们想在两个或以上的表获取其中从一个表中的行与另一个表中的行匹配的数据,这时 ...

  2. java多线程(简单介绍)

    简单介绍 线程是程序运行的基本执行单元.当操作系统(不包括单线程的操作系统,如微软早期的DOS)在执行一个程序时,会在系统中建立一个进程,而在这个进程中,必须至少建立一个线程(这个线程被称为主线程)来 ...

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

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

  4. java fork/join简单实践

    我们知道,java8中有并行流,而并行流在后台的实现是通过fork/join池来完成的,例如: List<Integer> a = buildList(); List<Integer ...

  5. Thread.join()方法

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B.t.join() ...

  6. Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  7. 【转载】JMeter学习(一)工具简单介绍

    JMeter学习(一)工具简单介绍 一.JMeter 介绍 Apache JMeter是100%纯JAVA桌面应用程序,被设计为用于测试客户端/服务端结构的软件(例如web应用程序).它可以用来测试静 ...

  8. TCP同步与异步及阻塞模式,多线程+阻塞模式,非阻塞模式简单介绍

    首先我简单介绍一下同步TCP编程 与异步TCP编程. 在服务端我们通常用一个TcpListener来监听一个IP和端口.客户端来一个请求的连接,在服务端可以用同步的方式来接收,也可以用异步的方式去接收 ...

  9. MPI编程简单介绍

    第三章MPI编程 3.1 MPI简单介绍 多线程是一种便捷的模型,当中每一个线程都能够訪问其他线程的存储空间.因此,这样的模型仅仅能在共享存储系统之间移植.一般来讲,并行机不一定在各处理器之间共享存储 ...

随机推荐

  1. 缺少动态连接库.so--cannot open shared object file: No such file or directory

    总结下来主要有3种方法:1. 用ln将需要的so文件链接到/usr/lib或者/lib这两个默认的目录下边 ln -s /where/you/install/lib/*.so /usr/lib sud ...

  2. Ansible-Tower快速入门-4.以超级用户帐号登录【翻译】

    以超级用户帐号登录 首先,登录tower需要使用tower服务器所在的URL,格式如下:https://<tower server name>/ 注意:tower安装了一个自签名证书用于H ...

  3. MySQL数据库权限操作指南

    -- 创建用户 CREATE USER 'dongrichtest' IDENTIFIED BY 'dongrichtest'; -- 新增后删除需要刷新权限 FLUSH PRIVILEGES; -- ...

  4. android沉浸式状态栏设置(4.4以上版本)

    其实设置比较简单,我用了小米和htc的几款机型都可以用. 主要代码就是这个(注意要在Activity的setContentView之前调用才行) /** * 开启沉浸式状态栏 * */ public ...

  5. python 抓取百度音乐

    # coding:utf-8 import urllib2 import re import urllib import chardet from json import * category = ' ...

  6. Cantor的数表

    题目描述 如下数列,前5项分别是1/1,1/2,2/1,3/1,2/2…….输入n,输出第n项. 1/1   1/2   1/3   1/4   1/5 2/1   2/2   2/3   2/4 3 ...

  7. Loadrunner进行接口自动化测试

    我们以测试豆瓣api获取图书信息的接口为例 接口的信息如下: 接口ip:https://api.douban.com/v2/book/:id 接口返回值:status=200 返回数据: { - (图 ...

  8. AFNetworking 3.0

    AFN 一.什么是AFN 全称是AFNetworking,是对NSURLConnection的一层封装 虽然运行效率没有ASI高,但是使用比ASI简单 在iOS开发中,使用比较广泛 AFN的githu ...

  9. 设置jdk的编码

    在环境变量中:  AVA_TOOL_OPTIONS-Dfile.encoding=utf-8 -Duser.language=en -Duser.country=US

  10. 《C#编程宝典:十年典藏版》阅读笔记(1)

    1.运行时错误,使用Checked块语句进行异常检查与抛出异常. 2.值类型使用线程堆栈保存数据,数据大小大概为1M左右,引用类型使用托管堆保存数据,可以无限分配空间,因为有一个GC垃圾回收机制存在, ...