1.进程、线程与任务
- 进程(process):是程序的运行实例,运行一个Java程序的实质是启动一个Java虚拟机进程,进程是程序向操作系统申请资源(如内存空间和文件句柄)的基本单位。
- 线程(Thread):是进程中可独立执行的最小单位,同一个进程中的所有线程共享该进程中的资源,如内存空间、文件句柄
- 任务:线程所要完成的计算
2.多线程编程简介
事实上,Java平台中的一个线程就是一个对象,我们在面向对象编程的基础上实现多线程编程
多线程编程类似“和尚挑水”,可能提高效率,也可能降低效率
3.Java线程API简介
java.lang.Thread是Java平台对线程的实现,Thread类或者子类的一个实例就是一个线程
3.1线程的创建、启动与运行
run方法
每个线程都有其要执行的任务,线程的任务处理逻辑可以再Thread类的run实例方法中直接实现或者通过该方法进行调用,所以,run方法相当于线程的任务处理逻辑的入口方法,它由Java虚拟机在运行相应线程时直接调用,而不是由应用代码进行调用
start方法
启动相应的线程,实质是请求Java虚拟机运行相应的线程,而这个线程具体何时能够运行由线程调度器scheduler来决定,因此,start方法调用结束后并不意味着相应线程已经开始运行,可能稍后运行,也可能不运行。
创建线程
Thread类的两个常用构造器:
Thread():覆盖Override掉run方法并在该方法中实现线程任务处理逻辑Thread(Runnable target):创建一个java.lang.Runnable接口的实例,并在该实例的run方法中实现任务处理逻辑,然后以该Runnable接口实例作为构造器的参数直接创建(new)一个Thread类的实例
方式1
可能的运行结果:
方式2
线程属于“一次性用品”,不能通过重新调用一个运行结束的线程的start方法来使其重新运行,多次调用同一个Thread实例的start方法会抛出
IllegalThreadStateException异常Java平台中,一个线程就是一个对象,对象的创建离不开内存空间的分配,与创建其他类型的Java对象不同的是,Java虚拟机会为每个线程分配调用栈(Call Stack)所需的内存空间
调用栈:用于跟踪Java代码(方法)间的调用关系以及Java代码对本地代码(Native Code,通常是C代码)的调用。
Java线程是一个对象,同时可以看到run方法是public修饰的,这意味着从语法角度来看,可以直接调用线程的run方法,但要避免这么做,因为违背了创建线程的初衷!
3.2Runnable接口

可以看到,Runnable接口只定义了一个方法
Runnable接口可以被看做对任务进行的抽象,任务的处理逻辑就体现在run方法中。Thread类实际上是Runnable接口的一个实现类,其对Runnable接口的实现源码如下:

源码解读:
- 实例变量target的类型为Runnable
- 如果相应的线程实例是通过构造器
**Thread(Runnable target)**创建的,那么target的为构造器中的参数值,否则target的值为null - 因此,Thread类所实现的任务处理逻辑是:要么什么也不做(target为null),要么直接执行target所引用的Runnable实例所实现的任务处理逻辑
- 这种处理逻辑决定了创建线程的两种方式:一种是在Thread子类的run方法中直接实现,另一种是在一个Runnable实例中实现,然后由Thread类中的run方法负责调用
线程两种创建方式的区别:

代码比较
https://www.cnblogs.com/haohaooldtime/p/14037282.html
3.3线程的属性

3.4Thread类的常用方法


3.5Thread类的一些废弃方法

4.线程的层次关系

在Java平台中,一个线程是否是一个守护线程默认取决于其父线程
默认情况下,父线程是守护线程的话,子线程也是守护线程;同理,若父线程为用户线程,子线程也是。但也可以调用线程的setDaemon方法作出相应设置
注意:父线程和子线程之间的生命周期没有必然的联系,比如父线程运行结束,子线程可以继续运行
6.线程的生命周期

线程的状态可以通过
**Thread.getState()**调用来获取,返回值类型是一个枚举类型(Enum)
NEW:一个已创建而未启动的线程处于该状态。由于一个线程实例只能被启动一次,因此一个线程只可能有一次处于该状态。




一个线程在其整个生命周期中,只可能有一次处于NEW状态和TERMINATED状态
7.小结

