1.1 多线程详细介绍
a) 多线程概述
l
线程:线程是程序中的执行绪 ( 执行路径 / 控制单元 ) ,即 CPU 的最小单位是线程而不是程序。
l 多线程:
计算机当中可以 ” 同时 ” 执行多个执行路径的代码, Java 支持多线程, Java 是多线程执行的。
l 线程调度模型:
分时调度模型
所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片。
抢占式调度模型
优先让优先级高的线程使用 CPU ,如果线程的优先级相同,那么会随机选择一个 ( 线程随机性 ) , Java 使用的为抢占调度模型。
b) Java的多线程实现方式
Java
共有三种常见的实现方式,这里介绍前两种,下一个案例中介绍最后一种。Thread 类是 Java 支持多线程的具体类,凡是 Thread 的子类均为一个线程。
线程需要创建,并使用 start 方法开启,开启线程后,线程才会执行。
常用方法:
public void start() // 开启线程
public static Thread currentThread() // 获取当前线程
public final String getName() // 获取线程名称
public static void sleep(long millis) // 线程睡眠(等待)指定毫秒
更复杂的方法参考 API
l 方式 1 :定义类继承 Thread 类,直接重写 run 方法。
定义类继承,重写Thread类中的run方法即可,但是这种方式在实现数据共享时比较麻烦。并且无法规避Java的单继承规则。
步骤:
定义类继承Thread类
重写run方法
在测试类中创建该定义好的线程对象
开启线程
l 方式 2 :线程与线程执行目标分离方式。
这里需要使用到线程执行目标: Runnable 接口。
如果没有重写线程的 run 方法则每个线程开启后并不知道要执行什么,线程执行目标类负责制定该线程要执行的代码,该类只有 run 方法, run 方法即线程最终会执行的方法。相当于该线程中的 main 方法。
步骤:
定义类实现 Runnable
重写 run 方法
在测试类中创建线程执行目标类对象
在测试类中使用线程执行目标类对象创建线程对象
开启线程
c) synchronized补充
这里我们对锁进行进一步强调:锁可以是任意类型的对象,只要多个线程使用同一把锁就可以使多个线程操作相同数据时同步。
当线程 1 执行到 synchronized 代码块内时成为获取同步锁,其他线程等待该线程的同步代码块内执行完毕并释放锁后抢到 CPU 才可以执行。
Lock 锁:除了 synchronized 代码块外, Lock 锁是更灵活地同步解决方法。我们涉及到的同步问题并不复杂,这里无需使用。
d) synchronized补充
与同步代码块相同,
java
还提供了同步方法来解决同步问题。同步方法的格式:在方法的返回值前加 synchronized 关键字,该方法的锁默认使用 this 。
如果方法为静态方法,则锁默认使用该类的字节码文件对象:类名
.class
e) 线程死锁
同步操作
一张图:线程生命周期图
相同的锁锁住的代码,不会重复