当前位置: 首页 > news >正文

Java:多线程

多线程

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

并发和并行

并发:在同一时刻,有多个指令在单个CPU上交替执行

并行:在同一时刻,有多个指令在多个CPU上同时执行

实现方式

1·继承Thread类的方式进行实现

*多线程的第一种启动方式:

1.自己定义一个类继承Thread

2.重写run方法

3.创建子类的对象,并启动线程

2·实现Runable接口的方式进行实现

多线程的第二种启动方式:

1.自己定义一个类实现Runnable接口

2.重写里面的run方法

3.创建自己的类的对象

4.创建一个Thread类的对象,并开启线程

3·利用Callable接口和Future接口方式实现

1.创建一个类Mycallable实现callable接口
2.重写call(是有返回值的,表示多线程运行的结果)


3.创建Mycallable的对象(表示多线程要执行的任务)

4.创建Futureask的对象(作用管理多线程运行的结果)

5.创建Thread类的对象,并启动(表示线程)

三种方法的区别

Thread中常见的成员方法

线程优先级从1到10; 越低优先级越高

守护线程setDaemon

当其他非守护线程结束时候,守护线程就会陆续结束

出让线程/礼让线程

如果运行两个MyThread类对象则会,会使结果更加均匀,当运行到Thread.yield();就会把使用权让出去,重新分配

插入线程/插队线程

插入线程在某个线程中调用其他线程的jion方法,就会先把其他线程执行完

线程的生命周期

线程安全问题

在多个线程操作同一个数据时有时候会出现问题,问题是由线程执行顺序的随机引起的。

例如:

构造一类用来实现多个窗口的售票

再创建多个窗口来进行多个线程同时售票

结果出现了重复票和顺序和多票的问题,因为每个线程执行到每一步时候,执行权都有可能会被其它线程抢走,导致出现混乱

这时可以用同步代码块,让每一个线程都要执行完某一步骤执行权力才能让出去

同步代码块

把操作共享数据的代码锁起来

锁对象可以是任意的,但一定是唯一的

例如:static Object obj = new Object();(唯一的静态类)

MyThread.class (字节码文件对象,一定是唯一的)

就可以当作锁

特点1:锁默认打开,有一个线程进去了,锁自动关闭

特点2:当里面的代码都执行完毕,线程出来,锁自动打开,线程才可以进去

同步方法

就是把synchronized关键字加到方法上

格式:

特点1:同步方法是锁住方法里面所有的代码

特点2:锁对象不能自己指定:1·如果是静态方法锁对象就是当前方法的调用者:this 2·如果是静态方法,锁对象就是当前类的字节码文件对象

Lock锁

虽然我们可以理解同步代码块和同步方法的锁对象问题

但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,

为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作

Lock中提供了获得锁和释放锁的方法

void lock();获得锁

void unlock();释放锁

Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化ReentrantLock的构造方法

ReentrantLock(); 创建一个ReentrantLock的实例

死锁

是一种错误,当线程A拿到A锁的同时,线程B也拿到B锁了,就会导致A、B锁都锁了,线程A停在达到B锁这里,而线程B也无法拿到A锁

等待唤醒机制(生产者和消费者)

生产者和消费者模式是一个十分经典的多线程协作的模式

Java中的等待唤醒机制是一种线程间的通信方式,通过 Object 的 wait() 、 notify() 和 notifyAll() 方法来实现。

 
- 当一个线程执行到 wait() 方法时,它会释放当前持有的对象锁,并进入等待状态,直到其他线程调用 notify() 或 notifyAll() 方法来唤醒它。
 
-  notify() 方法会随机唤醒一个在该对象上等待的线程,而 notifyAll() 方法则会唤醒所有在该对象上等待的线程。被唤醒的线程不会立即执行,而是要等到调用 notify() 或 notifyAll() 方法的线程释放锁后,才会去竞争锁,获取到锁后才能继续执行。


用阻塞队列实现

线程的六种状态

线程池

主要原理:

1·创建一个池子,池子中是空的

2·提交任务时,池子就会创建新的线程对象,任务执行完毕,线程归还给池子,下回再次提交任务时,不需要创建新的线程,直接复用已有的线程即可

3·但是如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待
 

Executors:线程池的工具类通过调用方法返回不用类型的线程池对象。

1·创建一个没有上线的线程池

2·创建一个最多可以创建3个线程的线程池

自定义线程池

安排任务的顺序

1·先使用核心线程的数量来运行任务

2·诺核心线程数量小于要运行的任务,剩余任务则在阻塞队列排队

3·诺还添加任务到阻塞队列都装不下了,就会将后面装不下的任务交给:“线程池中最大线程数量 - 核心线程数量”的线程处理。也就是说后面的任务会先被其他线程处理(除了核心线程的),而阻塞队列中的任务就接着排队

4·诺线程池中最大的线程数量都已经被使用了,那么就会抛弃再加入的任。

5·诺“线程池中最大线程数量 - 核心线程数量”,已经被弃用“用TimeUnit”指定的时间那么就会从线程池中删除

线程池的拒绝策略

线程池大小选择

1·CPU密集型运算

CPU运行比较多,读取文件较少:最大并行数+1

2·I/O密集型运算

读取文件较多:

相关文章:

  • 极刻AI搜v1.0 问一次问题 AI工具一起答
  • Kubernetes相关的名词解释Container(16)
  • Linux:进程:进程控制
  • AI软件栈:LLVM分析(六)
  • Shell脚本-变量的分类
  • 计算机组成与体系结构:内存接口(Memory Interface)
  • Linux学习笔记|入门指令
  • python生成动态库在c++中调用
  • 基于Spring Boot实现文件秒传的完整方案
  • Hibernate的组件映射
  • RPA系统应用通用文字识别技术,推动 RPA 在各个领域的广泛应用和发展
  • 信奥中的数学
  • 进程与线程:03 用户级线程
  • 系分论文《论数据中台建设的分析和应用》
  • HADOOP 3.4.1安装和搭建(尚硅谷版~)
  • uv运行一个MCP Server的完整流程
  • XAttention
  • 人工智能100问☞第9问:什么是AI芯片?
  • 基于SpringBoot的高校体育馆场地预约管理系统-项目分享
  • 理性决策与情绪偏差
  • 旁白丨无罪后领到国家赔偿,一位退休教师卸下了“包袱”
  • 对话地铁读书人|豪宅房产经纪人:读书使我免于抑郁
  • 平安银行一季度净赚超140亿元降5.6%,营收降13.1%
  • 香港美国商会喊话特朗普政府:许多成员已受影响,尽快解决当前局势
  • 教育部答澎湃:推动招生入学流程最优化、材料最简化
  • 汪元程已任湖北荆州市委书记