多线程基础

1.进程和线程,并行和并发
一个程序就是一个进程,一个程序中多个任务就是多个线程,进程表示资源分配的基本单位,线程是进程中执行运算的基本单位,也是调度运行的基本单位
2.为什么使用多线程
一段时间内,多个任务都需要有进展的情况,使用多线程会加大资源消耗,所以不是什么情况下都要用
比如redis,es,解决的是好不好的问题,没有也能用,就是速度慢,效率低
但多线程使用,解决的是能不能的问题
例如:
8:00数学 10:10语文 2:00英语 4:10政治
一个对象若干个功能,依次调用,做完一个再做另一个
如果并发执行
就是数学题做一半换成英语题,效率低,结果也不好
一个小时之内,跟5个人都在聊天
3.怎么使用
Java有多线程的功能,但是默认不开启
所以要使用有两步
(1)实现多线程(让一段代码,具备并发的功能)
两种方式:
继承Thread类,实现runnable接口,重写run方法

在这里插入图片描述
在这里插入图片描述
(2)开启多线程(让这段代码并发执行)调用Thread对象的start()方法
在这里插入图片描述
注意,这个类中,只有run方法中的内容才能并发,其他方法不能并发;直接调用run方法不能并发,得调用start方法,注意,这个方法是Thread类中的。
如果是实现runnable接口的类,还得封装成Thread对象,之后才能使用(使用接口都是因为需要继承其他的类,没办法)
4.线程安全
多条线程,使用同一资源,可能回出现安全问题
例如:
在这里插入图片描述
在这里插入图片描述
结果是:
在这里插入图片描述
原因,num–,在JVM中,分三步执行
取得num的值,操作计算num-1,对num进行赋值
三个步骤中,如果多个线程同时访问,就会出现上一个没做完,下一个就拿走去用的情况,这就是线程不安全
如果,这个方法上加同步关键字
在这里插入图片描述
只加这一个关键字,结果就是:
在这里插入图片描述
一个方法在处理num的时候,会给自个资源加锁,处理完成以后,释放所,其他线程才可以使用,用的时候也会先加锁,所以不会出现重复
5.线程的生命周期
首先,线程总共就5个状态
新建,new关键字创建一个线程对象(Thread对象),仅仅就是new了个对象,很单纯,也不会发生什么事
就绪,新建对象后,调用start方法,就处于就绪状态

运行,如果处于就绪状态的线程,获得了CPU资源,开始执行run方法中的代码,就是处于运行状态

死亡,run方法正常执行完,就是死亡状态
阻塞,主动调用sleep或被动接受一些阻塞式方法
在这里插入图片描述
(1)新建到就绪,就是start
(2)就绪到运行,就是获得处理器资源(不能人为强制干预,没有直接就让线程进入运行的方法)
(3)运行到就绪,失去处理器资源,yield方法
(4)运行到阻塞,基本的三种情况
(5)阻塞到就绪,一样
(6)运行到死亡,正常run方法结束,stop,call,Error
启动一个新的线程,成本比较高(Java代码线程开启涉及与操作系统的交互),当程序中需要创建大量生存期较短的线程时,应该使用线程池
怎么用,线程池一般是插件实现,框架实现
也就是别人写好,你去配置使用
6个重要参数
(1)corePoolSize(int)核心线程数
(2)maxPoolSize(int)最大线程数
(3)keepAliveTime(long)保持存活时间
(4)workQueue任务存储队列
(5)threadFactory(ThreadFactory)当线程池需要新的线程,就用这个类去创建
几个问题:
添加线程的规则(6)Handler(RejectedExecutionHandler)线程池无法接受任务的时候使用的拒绝策略
(1)线程数量小于corePoolSize,不管有没有执行任务,都会创建新的线程
(2)如果线程数量大于等于corePoolSize,但又小于maxPoolSize,就将任务放入队列
(3)如果队列已满,并且,线程数小于maxPoolSize,就创建新的线程
(4)如果队列已满,并且,线程数大于等于maxPoolSize,就根据拒绝策略,拒绝该任务
几种情况:如果,corePoolSize和maxPoolSize取一样的值,就会创建一个固定大小的线程池
一般理念是,线程池中保留较少的线程数,并且只有负载较大时才会增加(像超市收银)
如果maxPoolSize设置的值很大(int类型的极限),允许线程池容纳任意数量的并发任务,直到机器跑不动为止
如果使用无界队列,就可以一直排队,不增加线程
(5)如果新建线程之后,线程数大于corePoolSize,那么没有任务的线程,如果空闲时间大于keepAliveTime,就会被终止
(6)新的线程,默认是使用这个创建
在这里插入图片描述
创建出来的线程,都在一个组,有一样的优先级,都不是守护线程
(7)使用的队列
新的任务(超出核心数量的)会进入队列
在这里插入图片描述
直接交接,纯粹就是做个中转,不存储任务,敏捷性高,需要将最大线程数设置的大一些
无界队列,可以防止流量激增,处理速度赶不上提交速度,可能导致任务越来越多,就死机了
有界队列,可以设置队列大小,最合理最常用的
手动创建:
重点还是这几个核心参数
在这里插入图片描述
工作中,不要自己创建,容易出现内存溢出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值