相信大家看api文档是不会搞清楚join()这个方法真正意义的,下面我用几行代码尽量言简意赅的说一下:
public class ThreadTest {
public static void main(String[] args) throws Exception {
ThreadTest tt = new ThreadTest();
tt.testJoin();
}
public void testJoin() throws Exception {
MyThread mt1 = new MyThread();
mt1.start();
long start = System.currentTimeMillis();
// mt1.join();
System.out.printf("testJoin over. Cost %d ms.\n", System.currentTimeMillis() - start);
}
}
class MyThread extends Thread {
public void run() {
System.out.println(this.getName() + " start...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName() + " over.");
}
}
运行上面的代码,得到的结果可能如下(第一句和第二句位置不固定)
Thread-0 start...
testJoin over. Cost 0 ms. //是的,这句会先执行
Thread-0 over.
是的,
System.out.printf("testJoin over. Cost %d ms.\n", System.currentTimeMillis() - start);
这一句会先于
System.out.println(this.getName() + " over.");
执行,且,打印出的 Cost 会是0ms。
这是因为 执行 mt1.start(); 后,会启一个Thread-0线程,主线程继续执行,而Thread-0线程则sleep 1000ms,
所以,就会出现上面的状况。
那么,我们将上面程序中 注释掉的那句mt1.join(); 加上,就会出现下面的结果:
Thread-0 start...
Thread-0 over.
testJoin over. Cost 1000 ms.
再看API文档中对join()方法的描述:等待该线程终止。 该线程是哪个线程?在上面的代码中,指的就是mt1.start();所创造出来的线程。
----------延伸-----------
而,如果我们给join 加上 参数,
第一次是:
mt1.join(30);
结果是:
Thread-0 start...
testJoin over. Cost 31 ms.
Thread-0 over.
第二次是:
mt1.join(2000);
结果是:
Thread-0 start...
Thread-0 over.
testJoin over. Cost 1000 ms.// 这里是1000,而不是2000
分析一下原因:
两种状况可导致join(long millis)方法退出: 主线程isAlive==false;等待毫秒数>millis。
PS:语言表达能力有限,可能说的不清楚。。。
分享到:
相关推荐
在Java中,线程可以被视为程序的执行流,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存。本资料“Java Thread Programming”由Paul Hyde提供,包含了关于Java线程编程的理论知识和实践代码,...
- **Fork/Join框架**:用于解决大问题的分割和并行处理。 7. **Executor部分** - **Executor基础**:Executor接口是线程池的抽象,简化了线程的创建和管理。 - **ThreadPoolExecutor的定制**:可配置核心线程数...
除了这些基础工具,C++还提供了线程局部存储(thread_local)关键字,使得每个线程都有自己独立的变量副本,避免了线程间的数据共享问题。 总的来说,面向对象的多线程编程是一项复杂但强大的技术,它允许我们构建...
本教程将深入探讨C#中的多线程基础知识,以及如何通过实例来实现线程的控制和通信。 首先,我们需要理解线程的基本概念。在操作系统中,线程是执行单元,它代表程序的一个执行流程。每个线程拥有自己的栈空间,用于...
1. **Java基础知识**:这部分可能包括Java语法基础,如数据类型、变量、运算符、流程控制语句(if、for、while)、类与对象、封装、继承、多态等概念。此外,还有异常处理(try-catch-finally)、包管理、接口、内部...
1. **Java基础知识**: - 类与对象:理解面向对象的基本概念,包括封装、继承和多态。 - 访问修饰符:public、private、protected以及默认(包访问)的区别。 - 构造器:用于初始化新创建的对象。 - 抽象类与...
1. Java基础知识:这包括但不限于Java语法、面向对象编程概念(封装、继承、多态)、异常处理、类与对象、接口、包的使用等。理解类加载器的工作原理以及内存管理也是重要的知识点。 2. 集合(必会):Java集合框架...
### Java就业培训教程知识点概述 ...通过以上章节的内容梳理,可以清晰地了解Java编程从基础语法到高级特性的各个方面,有助于初学者构建扎实的基础知识体系,并为进一步深入学习打下坚实的基础。
Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据主导地位。针对大公司的Java面试,面试官通常会从基础知识、数据结构与算法、多线程、JVM原理、设计模式、数据库、网络知识等多个方面来考察候选人...
1. **Java基础知识**: - **类与对象**:理解面向对象编程的基本概念,包括封装、继承、多态。 - **内存管理**:熟悉Java内存区域,如栈、堆、方法区,以及垃圾回收机制。 - **异常处理**:了解如何使用try-catch...
本文将深入探讨多线程服务器的基本原理、线程的基础知识以及如何利用多线程技术来构建并发服务器。 #### 二、线程基础知识 **1. 线程的概念** 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是...
- **Java堆**:所有线程共享的一块内存区域,用于存放对象实例。 - **方法区**:存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 ### 类加载 #### 类的加载过程 - **加载**:找到类...
- IoC容器和AOP(面向切面编程)的基础知识。 - Spring框架的主要模块及其功能。 9. **Hibernate**: - ORM映射的高级特性,如懒加载、缓存等。 - 查询语言(HQL)的使用。 以上就是Java程序员需要掌握的一些...
- 网络编程:TCP/IP协议、套接字编程等基础知识。 "java面试300讲MD答案课件"通过详尽的讲解和实例,为面试者提供了全面的准备指南,覆盖了Java开发者所需的核心技能和知识点,有助于提升面试成功率。通过学习和...
- **解释**: Java设计之初的目标之一就是“一次编写,到处运行”。它通过JVM实现了跨平台特性,使得Java程序可以在任何安装了JVM的操作系统上运行。 #### 24. 抽象类与接口的区别 - **知识点**: 抽象类与接口在Java...
【Java学习+面试指南】是一份综合性的资源,旨在帮助Java程序员巩固基础知识并为面试做好准备。这份指南涵盖了Java编程的各个方面,从基础语法到高级特性,从设计模式到并发编程,从数据结构到算法,全方位提升你的...
1. **Java基础知识**: - 数据类型:了解基本数据类型(整型、浮点型、字符型、布尔型)以及它们的内存占用和范围。 - 变量与常量:理解变量的声明、初始化和作用域。 - 类与对象:掌握类的定义、对象的创建及...
Java企业面试题是程序员在求职过程中常常面临的一种挑战,它主要涵盖了Java编程语言的基础知识、高级特性、框架应用、设计模式、并发编程、数据库交互、网络编程等多个领域。以下是一些可能出现在Java企业面试中的...
### Java多线程并发实战知识点解析 #### 一、引言 在计算机科学领域,**多线程**和**并发...通过深入理解Java多线程并发的基础知识及其内存管理机制,开发者可以更好地设计和优化多线程应用,提高系统的性能和稳定性。