闲聊线程

此篇为闲聊篇。如果出现知识点不做解释。

说到线程,首先想到的就是线程和进程的关系。这俩最主要的区别就是一个是系统资源的最小分配单位,一个是执行的最小单位。进程为啥是最小分配资源,想想JVM,它就是个进程。操作系统把资源给了JVM剩下的就是JVM自己处理了。有点像开发组和运维的感觉,运维并不想管你如何开发,更不想管你用的是什么语言,只有在开发人员需要资源的时候知会一下运维就行。而线程呢,就是你只会的这个动作,啥时候cpu想起来了,啥时候就处理了。

线程最主要的就是并发

为什么并发会导致服务器的崩溃呢。先说线程过多的情况,系统运行是需要消耗cpu的吧,因为毕竟要维护操作系统的基本功能,当线程创建过多,cpu把能分得都分了,但是创建线程的请求还是不断地堆积,而堆积总的有个地方去堆积吧,这就出现了个类似队列的结构,而维持这个结构又需要内存,整个系统消耗的没有增加的多,最终内存不断增加以至于内存爆满,然后还有任务进来,而这些任务还是操作系统的命令,不能放着不管,然后连cpu运行所需要的内存都开不出来的时候,程序就运行不下去的,进而变成大量的死锁,最终所有核都运行不了了。然后服务器就崩溃了。

这个时候就会问用线程池啥的不就行了,还是那个问题,用了线程池就要有队列去维持请求,处理速度跟不上就会堆积,然后内存就崩了。那为什么不限制队列长度,多久就抛异常打日志呢。这个还是一个问题,实用性,比如买票,总不能人家一顿点然后没反应吧。为了避免堆积,然后就出现了,负载均衡。反正数据库还是那个库,只要我服务器的代码是一致的就好,我接请求的时候选个运行少的服务不就好了,(不去解释负载机制,和Springcloud的负载思路),然后大家又发现了一个问题,像是mysql,sql运行要是建立连接的,等sql运行完了sql给你返回个结果。这会带来个问题,代码运行效率问题,比如一些日志,一些不用返回结果的业务逻辑,然后大家想,我们把任务执行队列外置不就行了,让别的服务器去处理这些任务。然后就出现了消息队列中间件,kafka mq 什么的 redis也能做。

因为是闲聊感觉上面跑题了。

接下来说说多线程的锁部分

主要就是java自己的锁,其实就俩,一个是sy 一个lock锁,这两个底层实现不同,所以效率也不同,一个是锁升级(过程中有自旋),一个是自旋。

关于锁,volatile关键字是很重要的,它有两个功能,一个是内存可见,一个是防止重排。

先说一下为什么会出现内存可见性问题,

因为内存有远近,所以对于cpu来说读取数据就是要耗时的,不可能每次算一个数据都从内存去读。于是乎为了方便,cpu就有一块很小的内存,用来存一些运算数据。

而这个数据是要从内存读的。需要进行一层一层的复制。所以cpu里面的不是真正的数据,而是内存中数据的备份值。如果cpu运行比较繁忙cpu中的值不一定更新。然后就可能导致数据不一致,测试用例可以去看一个有趣的demo

volatile是如何解决的呢,简单来说在操作指令上,volatile的读和写是和普通的有区别的,当cpu执行volatile读的时候会强制更新cpu中的内存。

防止重排序则是通过重排序策略,对指令集进行整理。

当然也有redis锁,就把他当成个会告诉的拿锁成没成功的指令就好,具体redis原理不进行解释。

当然mysql锁也有其实跟redis这个差不多,唯一区别就是通过版本号去实现罢了,调用的话基本都是自旋。​​​​​​

接下来就是关于一些跟锁相关的数据结构

基本也没几个 主要是concurrent系列的和table系列的,底层的话可以去读源码。

当然还有callable future runable countdownlatch。

之后便是阻塞队列系列了。

接着线程池相关。

大致就这些,阻塞队列和concurrent系列基本和普通版本没啥区别,基本就是加了个锁保证同步,该是链表还是链表,该是红黑树还是红黑树。

线程池的话基本上就是阻塞队列和callable runable的封装。

闲聊结束

基本上能想到暂时就这些了,以后想到再追加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值