这里写目录标题
活动地址:CSDN21天学习挑战赛
1. 什么是多线程
- 线程(thread)是一个程序内部的一条执行路径。
- 我们之前启动程序执行后,main方法的执行其实就是一条单独的执行路径。
- 程序中如果只有一条执行路径,那么这个程序就是单线程的程序。
- 多线程是指从软硬件上实现多条执行流程的技术。
- 例如:消息通信、淘宝、京东系统都离不开多线程技术。
2. 多线程的创建
2.1 继承Thread类
Thread
类
- Java是通过
java.lang.Thread
类来代表线程的。- 按照面向对象的思想,
Thread类
应该提供了实现多线程的方式。
多线程的实现方案一:继承Thread类
- 定义一个子类MyThread继承线类
java.lang.Thread
,重写run()
方法 - 创建
MyThread类
的对象 - 调用线程对象的
start()
方法启动线程(启动后还是执行run方法的)
方式一优缺点:
- 优点:编码简单
- 缺点:线程类已经继承Thread,无法继承其他类,不利于扩展。
2.2 实现Runnable接口
多线程的实现方案二:实现Runnable接口
- 定义一个线程任务类MyRunnable实现Runnable接口,重写
run()
方法。 - 创建MyRunnable任务对象。
- 把MyRunnable任务对象交给
Thread
处理。 - 调用线程对象的
start()
方法启动线程。
- Thread的构造器
方式二优缺点:
- 优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
- 缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。
多线程的实现方案二:实现Runnable接口 (匿名内部类形式)
- 可以创建Runnable的匿名内部类对象。
- 交给Thread处理。
- 调用线程对象的
start()
启动线程。
2.3 JDK 5.0 新增Callable接口
多线程的实现方案三:利用Callable、FutureTask接口实现。
- 得到任务对象
- 定义类实现Callable接口,重写call方法,封装要做的事情。
- 用FutureTask把Callable对象封装成线程任务对象。
- 把线程任务对象交给Thread处理。
- 调用Thread的start方法启动线程,执行任务
- 线程执行完毕后、通过FutureTask的get方法去获取任务执行的结果。
FutureTask的API
方式三优缺点:
- 优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
- 可以在线程执行完毕后去获取线程执行的结果。
- 缺点:编码复杂一点。
3种方式对比
3. Tread的常用方法
Thread常用API说明
- Thread常用方法:获取线程名称getName()、设置名称setName()、获取当前线程对象currentThread()。
- 至于Thread类提供的诸如:yield、join、interrupt、不推荐的方法 stop 、守护线程、线程优先级等线程的控制方法,在开发中很少使用,这些方法会在高级篇以及后续需要用到的时候再为大家讲解。
Thread获取和设置线程名称
Thread类获得当前线程的对象
- 注意:
- 此方法是Thread类的静态方法,可以直接使用Thread类调用。
- 这个方法是在哪个线程执行中调用的,就会得到哪个线程对象。
Thread的构造器
Thread类的线程休眠方法
4. 线程安全
4.1 线程安全问题是什么、发生的原因
线程安全问题
- 多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题。
取钱模型演示
- 需求:小明和小红是一对夫妻,他们有一个共同的账户,余额是10万元。
- 如果小明和小红同时来取钱,而且2人都要取钱10万元,可能出现什么问题呢?
取钱案例线程安全问题演示
5. 线程同步
5.1 同步思想概述
加锁,把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,然后其他线程才能进来。
加锁:让多个线程实现先后依次访问共享资源,这样就解决了安全问题。
5.2 方式一:同步代码块
同步代码块
- 作用:把出现线程安全问题的核心代码给上锁。
- 原理:每次只能一个线程进入,执行完毕后自动解锁,其他线程才可以进来执行。
synchronized(同步锁对象) { 操作共享资源的代码(核心代码)}
锁对象要求
- 理论上:锁对象只要对于当前同时执行的线程来说是同一个对象即可。
锁对象的规范要求
- 规范上:建议使用共享资源作为锁对象。
- 对于实例方法建议使用this作为锁对象。
- 对于静态方法建议使用字节码(类名.class)对象作为锁对象。
5.3 方式二:同步方法
同步方法
作用:把出现线程安全问题的核心方法给上锁。
原理:每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。
格式:
修饰符 synchronized 返回值类型 方法名称(形参列表) {
操作共享资源的代码
}
同步方法底层原理
- 同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。
- 如果方法是实例方法:同步方法默认用this作为的锁对象。但是代码要高度面向对象!
- 如果方法是静态方法:同步方法默认用类名.class作为的锁对象。
5.4 方式三:Look锁
Lock锁
- 为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock,更加灵活、方便。
- Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。
- Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来构建Lock锁对象。
Lock的API
本文含有隐藏内容,请 开通VIP 后查看