多线程高并发(上)

本文涵盖了进程内多线程高并发常用技术。

进程内高并发

简述

启动线程的3种方式

1:Thread

2:Runnable

3:Executors.newCacheThread

sleep(自动复活到就绪状态)

yield(让出一下cpu,返回到就绪状态)

join

OS启动的线程数要大于java启动的线程(GC线程)

状态:ready,running,new,terminated,waiting,blocked,timewaiting

synchronized

hotspot使用对象头拿出两位记录

锁升级

特性

有序性

既可保证原子性,又可保证可见性

可重入锁

举例:父子类都为sychronized,锁的是子类对象,调用父类还是锁的子类

出现异常锁会被释放

锁定目标

synchronized(o)

synchronized(this)

synchronized(T.class)

同一个classloader空间把T.class加载到内存是单例的,不同classloader之间不能访问

加了就不用加volatile

锁升级

偏向锁:对于第一个对象,刚开始只记录线程ID

如果有线程争用,升级为自旋锁,默认自旋10次,之后升级为重量级锁,成为等待状态,不占CPU

锁只能升级,不能降级

执行时间短(加锁代码),线程数少,用自旋。执行时间长,线程数多,用系统锁

优化

细化,由锁方法到锁变量

避免对象的引用发生改变

volatile

作用

保证线程可见性

MESI缓存一致性协议

禁止指令(二进制码)重排序

a=new A();申请内存,初始化,赋值

保证原子性并不能保证重排序

读屏障或者写屏障可以防止指令重排序

不能保证原子性,要想保证原子性就用synchronized或者AtomicInteger

CAS

无锁,优化自旋

类本身是原子性的,但是不能保证多个方法连续调用是原子性的

CAS操作是CPU指令级别的支持

ABA问题:1、加版本号;2、AtomicStampedReference

如果基础类型无所谓;引用类型

Unsafe

靠CPU的原语来实现

并发特别高的情况:longadder(分段锁)->Atomic(无锁)->Sync(锁)

分段锁也是cas操作

ReentrantLock

finally unlock

ReentrantLock尝试某些次

可以对interrupt()方法做出响应

true公平锁,可以指定不公平或者公平;sync只有不公平

reen vs sync

cas vs sync锁升级

trylock

interrupt()

可以代替sync

公平和非公平锁

reen condition

CountDownLatch

await

countDown(原子性)

与join

join必须要等到线程结束

barrier

Phaser

遗传算法

barrier的升级版

readwritelock(读写锁)

共享锁+排它锁

stampedLock(升级态)

semaphore

acquire、release

令牌、限流

exchanger

两两交换

LockSupport(JDK1.6)

park unpark

ArrayList非线程安全

notify不释放锁

wait释放锁

condition

lock.newCondition生成一个等待队列

生产者唤醒消费者,消费者唤醒生产者

AQS(CLH)

核心是state,volatile int

state随着子类变化

是一个双向链表线程队列

向队列加东西用的是compareAndSetState

compareAndSetTail 自旋 用CAS代替了锁定整条链表的操作

varhandler

指向某对象的引用

compareAndSet int 为原子性操作

1.通过handle普通属性也可以完成原子性操作

2.比反射快直接操作二进制码

ThreadLocal

set get不能获取到对象

声明式实物,保证同一个connect

引用

new A();

System.gc属于fullGC

SoftReference内存不够用先回收一次,在直接干掉,做缓存使用

只要垃圾回收就会回收

ThreadLocal set() extend weakreference

内存泄漏,漏了一块

tl消失,ThreadLocal回收 务必要tl.remove

管理堆外内存,用来回收堆外内存

PhantomReference

垃圾回收看到就干掉,被干掉后收到一个通知(队列里添加一个值),队列里有值了就可以回收 堆外内存了Unsafe.allocMemory Unsafe.freeMomory

线程池

callable

和callable一样,只不过callable有返回值

用来拿callable的执行结果

future=service.submit异步操作

future.get阻塞

FutureTask

FutureTask->RunnableFuture->FutureCallable

CompletableFuture

一种任务的管理类

ForkJoin

线程池(2种)

ThreadPollExecutor(7个参数)

池子用的是hash

work

AddWorker
外层自旋,数量+1;启动worker加锁
thread
runnable AQS

参数

核心线程数coreThreadSize
核心线程中的线程,即使时间到了,也会占着
最大线程数maxThreadSize
生存时间liveTime
生存时间单位TimeUtil
任务队列
ArrayBlokingQueue
LinkedBlokingQueue(最大值是MAX_INTEGER)
线程工厂defaultThreadFactory
拒绝策略
线程池忙,任务队列满了,执行拒绝策略

ForkJoinPool

大任务分解成小任务,在集合

ForkJoinTask

RecursiveAction

Executor(线程池的工厂)

Single

LinkedBlockingQueue

Cached

SynchrousQueue

fixed

LinkedBlockingQueue

sheduled

DelayedWorkQueue

newWorkStealingPoll

每个线程都有自己的队列,自己的队列里面没有了去别的偷

push pop不需要阻塞 但是poll需要

底层用的是ForkJoinPoll

很像mapReduce

定时任务

Quartz

cron

Thread

一般情况下线程数=CPU*使用比*(1+W/C)

并发是任务提交,并行是任务执行,并行是并发的子集

Linux线程调度方法:1、优先级;2、按时间片(默认);3、实时

execute方法

核心线程->队列->非核心线程

disruptor

特点

对比concurrentLinkedQueue实现

JDK中没有concurrentArrayQueue

只需要维护sequenece

环形队列ringbuffer

12%8=12&(8-1)

event

eventFactory

直接覆盖,不用清楚旧的数据,降低GC频率

eventHandler

ProducerType

ProducerType.MULTI

ProducerType.SINGLE

等待策略(8种)

BlockingWait

YieldingWait

SleepingWait

JMH

parrelStream.foreach->foreach

容器

collection

list

copyOnWriteArrayList

写时复制

SynchronizedList

ArrayList

线程不安全

LinkedList

set

queue(针对高并发)

queue与list相比

添加了offer,peek,poll对线程友好的API

concurrentLinkedQueue

CAS
offer添加,线程安全
poll取并且remove,线程安全
peek取不会remove,线程安全
天生实现生产者,消费者模型

PriorityQueue

用堆实现

DelayQueue

阻塞
按时间进行任务调度
用PriorityQueue实现

ArrayQueue

BlockingQueue(线程安全)

LinkedBlockingQueue
put,阻塞
take,阻塞
底层用LockSupport.park实现
使用await,Condition->park
ArrayBlockingQueue
PriorityBlockingQueue
SynchrousQueue
容量为0
两个线程直接交换数据,手对手
TransferQueue
LinkedTransferQueue(等着人把资源取走才行,面对面付款,多人手对手)

Map

vector

hashtable和vector自带锁,基本不用

线程不安全

hashmap

hashmap

synchronizedHashMap,加锁了

concurrentHashMap

效率提高在读上面

无序

分段锁

CAS

将原本的一整个的Entry数组分成了若干段,分别将这若干段放在了不同的新的Segment数组中(分房间),每个Segment有各自的锁,以此提高效率

concurrentSkipListMap

有序

内部是SkipList(跳表)结构实现

猜你喜欢

转载自blog.csdn.net/u014162993/article/details/112140088