【Java21天挑战赛】多线程

发布于:2023-01-13 ⋅ 阅读:(279) ⋅ 点赞:(0)


活动地址:CSDN21天学习挑战赛

1. 什么是多线程

  • 线程(thread)是一个程序内部的一条执行路径。
  • 我们之前启动程序执行后,main方法的执行其实就是一条单独的执行路径。
    在这里插入图片描述
  • 程序中如果只有一条执行路径,那么这个程序就是单线程的程序。
  • 多线程是指从软硬件上实现多条执行流程的技术。
  • 例如:消息通信、淘宝、京东系统都离不开多线程技术。

2. 多线程的创建

2.1 继承Thread类

Thread

  • Java是通过java.lang.Thread 类来代表线程的。
  • 按照面向对象的思想,Thread类应该提供了实现多线程的方式。

多线程的实现方案一:继承Thread类

  1. 定义一个子类MyThread继承线类java.lang.Thread,重写run()方法
  2. 创建MyThread类的对象
  3. 调用线程对象的start()方法启动线程(启动后还是执行run方法的)

方式一优缺点

  1. 优点:编码简单
  2. 缺点:线程类已经继承Thread,无法继承其他类,不利于扩展。

2.2 实现Runnable接口

多线程的实现方案二:实现Runnable接口

  1. 定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法。
  2. 创建MyRunnable任务对象。
  3. 把MyRunnable任务对象交给Thread处理。
  4. 调用线程对象的start()方法启动线程。
  • Thread的构造器

在这里插入图片描述

方式二优缺点:

  1. 优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
  2. 缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。

多线程的实现方案二:实现Runnable接口 (匿名内部类形式)

  1. 可以创建Runnable的匿名内部类对象。
  2. 交给Thread处理。
  3. 调用线程对象的start()启动线程。

2.3 JDK 5.0 新增Callable接口

多线程的实现方案三:利用Callable、FutureTask接口实现。

  • 得到任务对象
  1. 定义类实现Callable接口,重写call方法,封装要做的事情。
  2. 用FutureTask把Callable对象封装成线程任务对象。
  • 把线程任务对象交给Thread处理。
  • 调用Thread的start方法启动线程,执行任务
  • 线程执行完毕后、通过FutureTask的get方法去获取任务执行的结果。

FutureTask的API

在这里插入图片描述

方式三优缺点:

  1. 优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
  2. 可以在线程执行完毕后去获取线程执行的结果。
  3. 缺点:编码复杂一点。

3种方式对比

在这里插入图片描述

3. Tread的常用方法

Thread常用API说明

  • Thread常用方法:获取线程名称getName()、设置名称setName()、获取当前线程对象currentThread()。
  • 至于Thread类提供的诸如:yield、join、interrupt、不推荐的方法 stop 、守护线程、线程优先级等线程的控制方法,在开发中很少使用,这些方法会在高级篇以及后续需要用到的时候再为大家讲解。

Thread获取和设置线程名称

在这里插入图片描述

Thread类获得当前线程的对象

在这里插入图片描述

  • 注意
  1. 此方法是Thread类的静态方法,可以直接使用Thread类调用。
  2. 这个方法是在哪个线程执行中调用的,就会得到哪个线程对象。

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 后查看

网站公告

今日签到

点亮在社区的每一天
去签到