本次决定专门写一篇线程系列的文章。讲清楚Java jvm在加载一个程序的时候起始到终止的生命线。
一、谈线程必须说一下进程(process)
进程如果大家打开任务管理器。
这些都是运行在操作系统上面的进程。可以说进程是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的基本单位。
可以说进程是线程的容器,一个进程是包含一个或多个线程的。
二、线程
一个线程就是进程中一个单一顺序的控制流,进程中的一个执行单元。在操作系统中是以进程为单位分配资源。每个线程都有各自的线程栈。自己的寄存器环境。自己的线程本地存储。
2.1主线程与子线程
JVM启动时会创建一个主线程。该主线程负责执行main方法。
那么在Java中如果A线程中创建了B线程,那么可以称B线程为A线程的子线程,A线程可以是B线程的父线程。
2.2串行、并发与并行 执行原理
我们线程开发中尤其是电商项目都是高并发。并发可以提高事物的处理效率。一段时间内可以处理完成更多的事。
那么并行可以理解为更严格、理想的并发。
2.3 时间片的概念
从硬件角度来讲,一个单核CPU一个处理器一次只能执行一个线程的情况下。那么处理器只能使用时间片轮换的方式,让CPU快速的在各个线程直线进行切换。那么用户看到的感觉是三个线程同时执行。
如果是多核CPU,那么就可以为不同的线程分配不同的CPU内核。
那么只有当一个线程抢夺到CPU的时间片是才有可能可以被执行。
三、线程的创建与启动
在Java中,创建线程两种方式继承Thread类 或者实现Runnable接口。
/**
* Description: 线程测试
*
* @author: 德鑫
* @since: 2020/09/22
*/
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("继承thread类创建的子线程!");
}
}
/**
* Description:
*
* @author: 德鑫
* @since: 2020/09/22
*/
public class MyRunnableThread implements Runnable{
@Override
public void run() {
System.out.println("实现Runnable接口创建的子线程");
}
}
/**
* Description: 测试
*
* @author: 德鑫
* @since: 2020/09/22
*/
public class MyTestThread {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start();
MyRunnableThread t2 = new MyRunnableThread();
Thread t = new Thread(t2);
t.start();
System.out.println("main!");
}
}
说一下这个start方法。首先调用线程的start()方法来启动线程。启动线程的实质就是请求JVM运行相应的线程,这个线程具体在什么时候运行有线程调度器(scheduler)决定。
有几个误区:
1、start方法的调用结束并不意味这个子线程开始运行了
2、新开启的线程会执行run方法。可以说run方法的开始运行才是标志着这个子线程开始运行
(如果上面两句话没懂建议多读几遍。在回头看看上面提到的时间片的概念)
3、如果开启了多个线程,start方法的调用顺序并不一定就是线程的启动顺序。
4、多线程运行结果与代码的执行顺序或者说调用顺序无关。