现有线程threadone、threadtwo和threadthree,想要的运行顺序为threadone->threadtwo->threadthree,应该如何处理?这里需要用到一个简单的线程方法join().

join()方法的说明:join方法挂起当前调用线程,直到被调用线程完成后在继续执行(join() method suspends the execution of the calling thread until the object called finishes its execution).

下面看一个例子:

/**
* Thread one for test.
*/
public class ThreadOne implements Runnable {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start..."); System.out.println(threadName + " end.");
}
}
/**
* Thread two for test.
*/
public class ThreadTwo implements Runnable {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start..."); System.out.println(threadName + " end.");
}
}
/**
* Thread three for test.
*/
public class ThreadThree implements Runnable {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start..."); System.out.println(threadName + " end.");
}
}
public class JoinMainTest {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start..."); Thread firstThread = new Thread(new ThreadOne());
Thread secondThread = new Thread(new ThreadTwo());
Thread thirdThread = new Thread(new ThreadThree()); // 1. no order thread run
firstThread.start();
secondThread.start();
thirdThread.start(); System.out.println(threadName + " end.");
}
}

上面得到的结果如下:

/**
*
main start...
Thread-0 start...
main end.
Thread-0 end.
Thread-1 start...
Thread-1 end.
Thread-2 start...
Thread-2 end.
*/

public class JoinMainTest {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start..."); Thread firstThread = new Thread(new ThreadOne());
Thread secondThread = new Thread(new ThreadTwo());
Thread thirdThread = new Thread(new ThreadThree()); // 2. thread run in order
try {
firstThread.start();
firstThread.join();
secondThread.start();
secondThread.join();
thirdThread.start();
thirdThread.join();
} catch (Exception ex) {
System.out.println("thread join exception.");
}
System.out.println(threadName + " end.");
}
}

这里得到的结果就是顺序执行的了:

/**
*
main start...
Thread-0 start...
Thread-0 end.
Thread-1 start...
Thread-1 end.
Thread-2 start...
Thread-2 end.
main end.
*/

再来看一下join()的源码,join()调用的就是join(0).可以看到,其实join就是wait,直到线程执行完成。

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;
}
}
}

Java中线程顺序执行的更多相关文章

  1. 面试官:Java中线程是按什么顺序执行的?

    摘要:Java中多线程并发的执行顺序历来是面试中的重点,掌握Java中线程的执行顺序不仅能够在面试中让你脱颖而出,更能够让你在平时的工作中,迅速定位由于多线程并发问题导致的"诡异" ...

  2. Java中如何保证线程顺序执行

    只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的.如果只是创建三个线程然后执行,最后的执行顺序是不可预期的.这是因为在创建完线程之后,线程执行的开始时间取决于CPU何时分配时间片,线程 ...

  3. Android中让多个线程顺序执行探究

    线程调度是指按照特定机制为多个线程分配CPU的使用权. 有两种调度模型:分时调度模型和抢占式调度模型. 分时调度模型:是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片. ...

  4. [转]JAVA程序执行顺序,你了解了吗:JAVA中执行顺序,JAVA中赋值顺序

    本文主要介绍以下两块内容的执行顺序,熟悉的大虾可以直接飘过. 一.JAVA中执行顺序 静态块 块 构造器 父类构造器 二.JAVA中赋值顺序 静态块直接赋值 块直接赋值 父类继承的属性已赋值 静态变量 ...

  5. 沉淀再出发:java中线程池解析

    沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...

  6. java中线程机制

    java中线程机制,一开始我们都用的单线程.现在接触到多线程了. 多线性首先要解决的问题是:创建线程,怎么创建线程的问题: 1.线程的创建: 四种常用的实现方法 1.继承Thread. Thread是 ...

  7. Java中线程的使用 (2)-多线程、线程优先级、线程睡眠、让步、阻塞

    Java中线程的使用 (2)-多线程.线程优先级.线程睡眠.让步.阻塞 (一)多线程使用方法 说明:创建每个新的线程,一定要记得启动每个新的线程(调用.start()方法) class Xc3 ext ...

  8. JAVA中线程同步方法

    JAVA中线程同步方法 1  wait方法:         该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所 ...

  9. 多线程(三) java中线程的简单使用

    java中,启动线程通常是通过Thread或其子类通过调用start()方法启动. 常见使用线程有两种:实现Runnable接口和继承Thread.而继承Thread亦或使用TimerTask其底层依 ...

随机推荐

  1. (转)Linux 文件系统:procfs, sysfs, debugfs 用法简介

    网址:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/ 1 前言 内核中有三个常用的伪文件系统:procfs,debugfs ...

  2. springside springmvc 的一个SB问题

    <form  id="inputForm" modelAttribute="order" action="${ctx}/myorder/orde ...

  3. c++ 异常处理 assert | try

    #include <iostream> #include <cassert> using namespace std; int main() { ; assert(i == ) ...

  4. spoj 247

    不管行列   总是先切割切割费用大的  代码比较烂 ...... #include <iostream> #include <cstdio> #include <cstr ...

  5. Kerbose

    http://blog.csdn.net/wulantian/article/details/42418231

  6. jvisualvm 使用

    和jconsole侧重于内存分析和检测不同,jvisualvm在线程分析方面更强大一些,下面简单介绍下使用: 1. 在要监控的java应用配置文件中,本例是apache-jmeter/bin/jmet ...

  7. hbase集群在启动的时候找不到JAVA_HOME的问题

    hbase集群在启动的时候找不到JAVA_HOME的问题,启动集群的时候报错信息如下: root@master:/usr/local/hbase-/bin# ./start-hbase.sh star ...

  8. Weblogic下部署的应用,当更新文件时需要重新安装部署

    JSP页面检查(秒):-1 Servlet重新加载检查(秒):-1 -1说明从不检查,故当更新文件时,需要重新部署,或重新安装部署.

  9. ios loading视图动画(模仿58同城)

    最近看了58同城的加载视图,感觉很不错,如下图: 所以想模仿写一个,下载58同城的app,解压,发现它用的是图片来实现的动画效果, 并不是绘制出来的,所以这就相对简单些了,其实整个动画的逻辑不复杂,无 ...

  10. Android:@id和@+id

    @id代表引用已有的id,而@+id是新增加一个id 如果使用@+id/name形式,当R.java中存在名为name变量时,则该组件会使用该变量的值作为标识.如果不存在该变量,则添加一个新的变量,并 ...