Java线程

1. 基本概念

1.1 进程和线程

进程(process):操作系统中独立运行的程序,一个运行的程序对应一个进程
多进程:一个操作系统同时运行多个程序

线程(thread):进程中的一个执行单元,负责进程中一个功能的执行
多线程:一个程序可以同时运行多个功能,即多线程,例如迅雷中同时执行多个下载任务

1.2 CPU时间片

CPU分配给各个程序的时间,即每个程序允许运行的时间
对于单核CPU,同一时间只允许运行一个程序,但是CPU在很短的时间内,会切换运行不同的程序,执行速度很快,所以看起来像是同时运行多个程序
对于多核CPU,确实可以并发执行多个程序

2. 创建线程

创建线程的两个方法
a. 继承Thread类
b. 实现Runnable接口

2.1 继承Thread类

继承Thread类
在这里插入图片描述

2.2 实现Runnable接口

1.实现runnable接口,重写run方法
2.创建线程Thread类对象的时候,调用带参runnable的构造方法

实现Runnable接口
匿名内部类

2.3 两种创建方式的对比

继承Thread类

1.线程执行的代码放在Thread类子类的run方法中
2.无法继承其他类

实现Runnable接口

1.线程执行的代码放在runnable接口实现类的run方法中
2.可以继承其他类,没有单继承的局限性
3.适合多个相同程序代码的线程处理同一个资源
4.增强代码的健壮性

3. 线程的生命周期

线程的生命周期

3.1 相关方法

线程执行完毕进入terminated状态,不可被重复使用,倘若死亡线程再次调用start方法,会抛出
Java.lang.IllegalThreadStateException

方法名作用说明
start启动线程,线程进入就绪状态(可运行状态)
sleep休眠线程,线程从执行状态进入阻塞状态静态方法
yield启动线程,线程进入就绪状态(可运行状态)静态方法
join暂停执行,等待另一个线程执行完再执行,执行状态进入阻塞状态X线程.join(),X线程插队先执行
interrupt中断线程的休眠或等待状态X线程.interrupt(),中断X线程的休眠或等待,会抛出中断异常
wait线程放弃对象锁,进入对象的等待池可以设置等待超时时间,超时之后自动唤醒
notify唤醒对象等待池中随机一个线程
notifyAll唤醒对象等待池中的所有线程

说明:

1
当前执行线程调用wait方法,释放锁,进入等待队列,当前锁持有线程执行notifyAll,唤醒所有等待队列中的>线程,进入锁池,等当前线程释放锁,锁池中的线程争抢锁,进入可运行状态,若执行notify则是唤醒任一线程
注:获取锁之后进入就绪状态而非运行状态,等待调度,一个对象对应一个锁池
2.
Thread的静态方法sleep和join都不会释放锁,线程会进入阻塞状态,等超时或其他线程执行完或其他线程中>断yield不是进入阻塞状态,是进入就绪状态Object的wait会释放锁,进入等待队列,等待其他线程的notify
注:只有获取对象锁之后,才能调用wait和notify方法
3.
新建状态-就绪状态-运行状态-阻塞状态-死亡状态
4.
实际上Thread内部state分别是NEW-RUNNABLE-BLOCKED-WAITING-TIMED-WAITING-TERMINATED
5.
io操作,sleep,join会让线程进入阻塞状态
6.
wait/notify/notifyAll
三个方法都必须在synchronized块中执行,必须在获取对象锁之后
必须是同一个对象,notify才能唤醒wait

验证线程被唤醒后从调用wait方法的地方继续往下执行
wait/notify
wait/notify

4. 线程间的通信

4.1 Synchronized

线程安全问题

多个线程操作共享数据发生的问题称为线程安全问题。

原因

当一个线程执行操作共享数据的关键代码时,执行到一部分,cpu时间片切换,另一个线程进入执行,则会导致线程安全问题。

解决方法

synchronized + 锁

添加synchronized的代码块称为同步代码块,添加synchronized的方法称为同步方法,它们能保护共享数据的安全。

synchronized
synchronized

4.2 锁池和等待池

锁池

每个对象都自带一把锁,一个对象对应一个锁池,当一个线程获得对象的锁,其他线程进入锁池等待锁的释放,然后争抢,争抢得到后进入就绪状态,等待调度。

线程执行synchronized块,没有获取到对象的锁,进入该对象的锁池
当锁被归还到对象,对象锁池中的线程竞争获取锁
获取锁的线程执行synchronized块,执行完毕之后释放锁

等待池

线程获取对象锁之后,调用对象的wait方法进入该对象的等待池
等待其他线程获取对象锁之后调用对象的notify和notifyAll方法,唤醒等待池中的线程进入锁池
当线程获取对象的锁之后,会从调用wait方法的地方继续往下运行

=锁池和等待池

4.3 生产者和消费者

生产者和消费者问题是线程同步的经典问题,线程的协同合作。
生产者
生产商品,商品数达到上限,停止生产
消费者
消费商品,商品数达到下限,停止消费

生产者和消费者问题无非是wait和notify方法的调用
设置一个上下限,到达限制处等待,未达限制时做自己的操作,同时唤醒等待线程

商品
商品
生产者
生产者
消费者
消费者
交易市场
交易市场

4.4 线程单例

自实现ThreadLocal

线程单例,线程做key,实例做value,为每一个线程提供一个本地副本。
同一个线程获取同一个实例,不同的线程获取不同的实例。
管理变量,提供线程局部变量,为变量在每一个线程中存储一个本地副本。

线程单例
线程单例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值