多线程
1.1、并发与并行
- 并发:指两个或者多个事件在同一时间段内发生的。
- 并行:指两个或者多个事件在同一时刻发生(同时发生)。
注意:单核处理器的计算机肯定是不能并行的处理多个任务的,只能是多个任务在单个CPU上并行运行。同理,线程也是一样,从宏观角度上理解线程是并行运行的,但是从微观角度上分析却是串行运行的,即一个线程一个线程的去运行,当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为线程调度。
1.2、进程与线程
进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程:线程是进程中的一个执行单位,负责当前进程中的程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。
线程调度:
分时调度
所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。
抢占式调度
优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢先式调度。
1.3、创建线程类
Java使用java.lang.Thread
类代表线程,所有的线程对象都必须是Thread类或者其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。Java中通过继承Thread类来创建并启动多线程的步骤如下:
1.定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。
2.创建Thread子类的实例,即创建了线程对象 。
3.调用线程对象的start()方法来启动该线程。
代码如下:
主线程测试类:
package com.itheima.demo05.Thread;
/**
* @date Created by 林春燕 on 2021/2/9 23:20
* @微信公众号 浅悦的编程时光
* @博客 https://nate-lin.gitee.io
* @GitHub https://github.com/nate-lin
* @Gitee https://gitee.com/nate-lin
*/
public class Person {
private String name;
public void run(){
//定义循环,执行20次
for (int i = 0; i < 20; i++) {
System.out.println(name+"-->"+i);
}
}
public Person(){
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.itheima.demo05.Thread;
/**
* @date Created by 林春燕 on 2021/2/9 23:16
* @微信公众号 浅悦的编程时光
* @博客 https://nate-lin.gitee.io
* @GitHub https://github.com/nate-lin
* @Gitee https://gitee.com/nate-lin
*/
import java.util.Arrays;
/**
* 主线程:执行主(main)方法的线程
*
* 单线程程序:java程序中只有一个线程
* 执行从main方法开始,从上到下依次执行
*
* JVM执行main方法,main方法会进入到栈内存
* JVM会栈操作系统开辟一条main方法通向cpu的执行路径
* cpu就可以通过这个路径来执行main方法
* 而这个路径有一个名字叫main(主)线程
*/
public class Demo01MainThread {
public static void main(String[] args) {
Person p1=new Person("浅悦");
p1.run();
System.out.println(0/0);//ArithmeticException: / by zero
//出现异常时,后面的“林春燕”不能执行,这就是单线程。
Person p2=new Person("林春燕");
p2.run();
}
}
效果如下