join在线程里面意味着“插队”,哪个线程调用join代表哪个线程插队先执行——但是插谁的队是有讲究了,不是说你可以插到队头去做第一个吃螃蟹的人,而是插到在当前运行线程的前面,比如系统目前运行线程A,在线程A里面调用了线程B.join方法,则接下来线程B会抢先在线程A面前执行,等到线程B全部执行完后才继续执行线程A。

而在JDK的解释中,join方法被解释成等待这个线程死亡,也就是等待这个线程全部执行完后才继续执行接下来的进程。

public class Test1 implements Runnable{

    @Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
} public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(new Test1(),"线程一");
Thread thread2=new Thread(new Test1(),"线程二");
Thread thread3=new Thread(new Test1(),"线程三");
thread1.start();
thread2.start();
thread3.start(); System.out.println("------------------主线程到此-------------------");
/*thread2.join(); */ for (int i = 0; i < 20; i++) {
System.out.println("主线程"+i);
}
} }

在上面这个例子中,在主线程里面开启了3个子线程,结果是主线程先执行完再执行其他线程。

加上让线程2先执行完再执行主线程join后

public class Test1 implements Runnable{

    @Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
} public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(new Test1(),"线程一");
Thread thread2=new Thread(new Test1(),"线程二");
Thread thread3=new Thread(new Test1(),"线程三");
thread1.start();
thread2.start();
thread3.start(); System.out.println("------------------主线程到此-------------------");
thread2.join(); //让线程2先执行完主线程才能继续执行 for (int i = 0; i < 20; i++) {
System.out.println("主线程"+i);
}
} }

结果是

/**
* join的用法,哪个线程调用join哪个线程就插队先执行
*/ public class Test{ public static void main(String[] args) throws InterruptedException {
//开启Father线程,满足Father需求
new Thread(new Father()).start();
} } class Father implements Runnable{ @Override
public void run() {
System.out.println("老爸要抽烟,发现没烟了,给了100块让儿子去买中华......");
Thread son=new Thread(new Son()); //让儿子去买烟
son.start(); //开启儿子线程后,儿子线程进入就绪状态等待CPU调度,不一定立即执行儿子线程,所以可能会出现儿子没把烟买回来老爸就有烟抽了
/* try {
son.join(); //让儿子先插队去买烟
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("儿子不见了,报警寻找");
}*/
System.out.println("老爸接过烟,把零钱给了儿子");
System.out.println("儿子很开心,出门去了游戏厅");
}
} class Son implements Runnable{ @Override
public void run() {
System.out.println("儿子接过钱蹦跶出了门");
System.out.println("路过游戏厅玩了10秒钟");
for (int i = 1; i <= 10; i++) {
System.out.println(i+"秒");
try {
Thread.sleep(1000); //此时休眠可能会让其他线程进行,出错率增加,通过join方法解决
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("赶紧去买烟");
System.out.println("回家把烟给老爸");
}
}

加入了join方法后,运行结果正确

try {
son.join(); //让儿子先插队去买烟
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("儿子不见了,报警寻找");
}

Java多线程学习——join方法的使用的更多相关文章

  1. 转载:Java多线程中join方法的理解

    转载自:http://uule.iteye.com/blog/1101994 thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A ...

  2. Java多线程中join方法详解

    join()方法用于让当前执行线程等待join线程执行结束.其实现原理是不停的检查join线程是否存活,如果join线程存活则让当前线程永远等待. join()方法部分实现细节 while(isAli ...

  3. Java多线程中join方法的理解

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

  4. Java多线程学习——wait方法(信号灯法/生产者消费者模式)

    信号灯法:以一个标志位来判断是否执行还是等待 public class TV { private String voice; //内容 private boolean flag=false; //信号 ...

  5. Java多线程学习——wait方法(管道法/生产者消费者模式)

    简单介绍管道法: 生产者生产数据输送到管道,消费者从管道拿出数据,管道为空消费者等待,管道满生产者生产,消费者消费生产者生产,生产者生产消费者消费. public class Corn { //要生产 ...

  6. java多线程学习

    在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口. 一.扩展java.lang.Thread类 package com.multithread.lea ...

  7. Java多线程学习(吐血超详细总结)

    本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的 ...

  8. Java多线程学习(转载)

    Java多线程学习(转载) 时间:2015-03-14 13:53:14      阅读:137413      评论:4      收藏:3      [点我收藏+] 转载 :http://blog ...

  9. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

随机推荐

  1. jmeter之Ramp-up Period(in seconds)

    [1]决定多长时间启动所有线程.如果使用10个线程,ramp-up period是100秒,那么JMeter用100秒使所有10个线程启动并运行.每个线程会在上一个线程启动后10秒(100/10)启动 ...

  2. etl-p

    java excel 导入数据库 上传文件包  解压导入excel包 导入mysql

  3. IDL_MCTK(MODIS Conversion Toolkit)

    1.CONVERT_MODIS_DATA CONVERT_MODIS_DATA [,IN_FILE= | | }] [,GEOLOC_FILE= | | }] [,CALIB_METHOD={ | | ...

  4. Java并发编程实战 第10章 避免活跃性危险

    死锁 经典的死锁:哲学家进餐问题.5个哲学家 5个筷子 如果没有哲学家都占了一个筷子 互相等待筷子 陷入死锁 数据库设计系统中一般有死锁检测,通过在表示等待关系的有向图中搜索循环来实现. JVM没有死 ...

  5. spring+mybatis事务配置(转载)

    原文地址:http://blog.csdn.net/wgh1015398431/article/details/52861048 申明式事务配置步骤 .xml文件头部需要添加spring的相关支持: ...

  6. InnoDB数据库 ibdata1 被删除后 的恢复方法

    前提条件:1  ibdata1 被删除 2  数据库文件还存在  特别是 ibd文件 3  原来数据库表结构及索引还在 恢复步骤: 1. 将原来的数据文件COPY到其它目录下. 2. 创建同名表,表结 ...

  7. 浅析为什么用高阶组件代替 Mixins

    转载来源 感谢分享 Mixins 引入了无形的依赖 应尽量构建无状态组件,Mixin 则反其道而行之 Mixin 可能会相互依赖,相互耦合,不利于代码维护 不同的 Mixin 中的方法可能会相互冲突 ...

  8. Django ckeditor增加编辑代码 功能

    前言 使用ckeditor这个组件的时候 对于长写博客的同学当然希望能有 增加代码这个功能按钮 而这个按钮 需要自己配置 我们的编辑器自然需要添加代码块的功能. 需要用到插件codesnippet,c ...

  9. SOA架构及其架构分析

    一.什么是SOA SOA即面向服务的架构.分为三层结构:表示层(服务层).中间业务逻辑层.数据访问层. SOA是一种粗粒度.松耦合服务架构,服务之间通过简单.精确定义接口进行通讯,不涉及底层编程接口和 ...

  10. 【Islands and Bridges】题解

    题目 题目描述 给定一些岛屿和一些连接岛屿的桥梁,大家都知道汉密尔顿路是访问每个岛屿一次的路线,在我们这个地图中,每个岛屿有个正整数的权值,表示这个岛屿的观赏价值.假设一共有N个岛屿,用Vi表示岛屿C ...