线程池原理剖析&锁的深度化

什么是线程池?
产生原因:经常创建,启动,销毁一个线程都是非常耗费时间。
好处:
1.降低资源消耗。重复利用已经创建的线程
2.提高响应速度。不需要等待线程创建(CPU调度)就能立即执行。
3.提高线程的可管理性。统一分配,调优,监控。


Java中使用线程 核心走ThreadPoolExecutor。
线程池使用方式?
Executor类封装好了四种线程池。
1.newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活
回收空闲线程,若无可回收,则创建线程。
2.newFixedThreadPool(##常用##)
创建一个定长线程池,可控制线程最大并发数,超出的线程会在
队列中等待。
3.newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
4.newSingleThreadExecutor
创建一个单线程化的线程池,他只会用唯一的工作线程来执行任务
保证所有的任务按照指定顺序(FIFO,LIFO,优先级)执行。

java中的线程池,核心走的是ThreadPoolExecutor类
ThreadPoolExecutor构造函数参数。
核心池大小(CodeOllSize)
MaiMumPoolSIZE线程池大小
Keepalivetimi终止时间
Unit超时秒数
核心线程池和最大线程池?
核心线程池:开始运行初始化池大小
线程缓冲队列
最大线程池:最大容量

线程池配置多少合适?
原则:
1.CPU密集:线程数和CPU数相同
2.IO密集:多配置线程数--2*cpu核数的线程数。
Runtinme.getRuntime().availableProcessors()
方法获得当前设备的cpu个数


Java锁机制:
悲观锁
乐观锁
分段锁
重入锁
读写锁
CAS无锁
自旋锁
排它锁
--分布式锁
什么是悲观锁?--自带排它锁
每次在拿数据的时候都会上锁。
begin
....
....for update
....
commit
缺点:只能保证一个连接操作。
什么是乐观锁?
乐观锁会乐观认为每次查询都不会造成更新丢失,利用版本字段控制。
version--版本控制。
update set state=1,set version=version+1 where orderId=1
and where version=version;
通过版本号+影响行数
if(影响行数>0){
update money set money=money+money where orderId=1;
}
需要在表中加入version字段
数据库保证原子性

重入锁?
锁在传递的时候能不能重复利用?
重入锁(传递给下一个方法,重复利用)与非重用锁(死锁)
递归使用同步。
等价于synchronized
好处:锁复用

读写锁?
假设你的程序中涉及到对一些共享资源的读和写操作,
且写操作没有读操作那么频繁。在没有写操作的时候,
两个线程同时读一个资源没有任何问题,
所以应该允许多个线程能在同时读取共享资源。
但是如果有一个线程想去写这些共享资源,
就不应该再有其它线程对该资源进行读或写
(译者注:也就是说:读-读能共存,读-写不能共存
,写-写不能共存)。这就需要一个读/写锁来解决这个问题。
Java5在java.util.concurrent包中已经包含了读写锁。
尽管如此,我们还是应该了解其实现背后的原理。

原子类底层实现保证线程安全?
CAS无锁机制效率比有锁机制高
CAS无锁机制其实和乐观锁类似概念。
CAS体系中有三个参数。
它包含三个参数CAS(V,E,N): V表示要更新的变量,
E表示预期值,N表示新值。仅当V值等于E值时,
才会将V的值设为N,如果V值和E值不同,
则说明已经有其他线程做了更新,
则当前线程什么都不做。最后,CAS返回当前V的真实值。

自旋锁是采用让当前线程不停地的在循环体内执行实现的,
当循环的条件被其他线程改变时 才能进入临界区




猜你喜欢

转载自blog.csdn.net/qq_38357267/article/details/80972994