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
image.png
可能的运行结果:
image.png


方式2
image.png


线程属于“一次性用品”,不能通过重新调用一个运行结束的线程的start方法来使其重新运行,多次调用同一个Thread实例的start方法会抛出IllegalThreadStateException异常

Java平台中,一个线程就是一个对象,对象的创建离不开内存空间的分配,与创建其他类型的Java对象不同的是,Java虚拟机会为每个线程分配调用栈(Call Stack)所需的内存空间

调用栈:用于跟踪Java代码(方法)间的调用关系以及Java代码对本地代码(Native Code,通常是C代码)的调用。


Java线程是一个对象,同时可以看到run方法是public修饰的,这意味着从语法角度来看,可以直接调用线程的run方法,但要避免这么做,因为违背了创建线程的初衷!
image.png


3.2Runnable接口

image.png
可以看到,Runnable接口只定义了一个方法

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

image.png
源码解读:

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

线程两种创建方式的区别:

image.png


代码比较

https://www.cnblogs.com/haohaooldtime/p/14037282.html


3.3线程的属性

image.png


3.4Thread类的常用方法

image.png
image.png


3.5Thread类的一些废弃方法

image.png


4.线程的层次关系

image.png
在Java平台中,一个线程是否是一个守护线程默认取决于其父线程

默认情况下,父线程是守护线程的话,子线程也是守护线程;同理,若父线程为用户线程,子线程也是。但也可以调用线程的setDaemon方法作出相应设置

注意:父线程和子线程之间的生命周期没有必然的联系,比如父线程运行结束,子线程可以继续运行


6.线程的生命周期

image.png

线程的状态可以通过**Thread.getState()**调用来获取,返回值类型是一个枚举类型(Enum)

NEW:一个已创建而未启动的线程处于该状态。由于一个线程实例只能被启动一次,因此一个线程只可能有一次处于该状态。
image.png
image.png
image.png
image.png
image.png

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


7.小结

image.png