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. zencart 显示Deprecated: Assigning the return value of new by reference is deprecated

    很多朋友的php程序当php的版本升级到5.3以后,会出现"Deprecated: Assigning the return value of new by reference is dep ...

  2. JAVA语言程序设计-笔记摘录

    JAVA 程序语言设计(基础篇) 笔记摘录 为避免输入错误, 不要在nextByte().nextShort().nextInt()等等后面使用nextLine() nextXXXXX()都称为令牌读 ...

  3. Eclipse中对一个项目进行复制粘贴为一个新项目

    1:对目标项目执行右键,选择“Copy”,然后在空白处右键,选择“Paste”结果如下图: 2:右键新项目,点击Properties, 3:打开Navigator视图 4:打开.settings文件夹 ...

  4. github readme 添加图片预览

    ![img](https://github.com/lanshengzhong/mina_alan/blob/master/screenshot/2.gif) ![图片加载失败的时候就会显示这段话]( ...

  5. UITextField实时监听输入文本的变化

    [textField addTarget:self action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditing ...

  6. springboot 在idea中实现热部署

    SpringBoot的web项目,在每一次修改了java文件或者是resource的时候,都必须去重启一下项目,这样的话浪费了很多的时间,实现了热部署,在每一次作了修改之后,都会自动的重启 第一步:引 ...

  7. nmon监控使用

    1.上传nmon_linux_x86_64文件到服务器 2.修改文件权限chmod 775 nmon_linux_x86_64 3.压测时需要执行以下命令监控服务器./nmon_linux_x86_6 ...

  8. matlab画二维直方图以及双y轴坐标如何修改另一边y轴的颜色

    1.首先讲一下如何用hist画二维直方图 x=[- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ...

  9. AJAX 实例解析

    AJAX 实例 为了帮助您理解 AJAX 的工作原理,我们创建了一个小型的 AJAX 应用程序: 实例 AJAX 不是新的编程语言,而是一种使用现有标准的新方法.深圳dd马达 AJAX 是与服务器交换 ...

  10. EF另一个 SqlParameterCollection 中已包含 SqlParameter。

    代码: SqlParameter[] commandParameters = new SqlParameter[]{ new SqlParameter("@CultID",filt ...