思维导图:高并发、多线程、锁、并发编程工具包、concurrent

思维导图:高并发、多线程、锁、并发编程工具包、concurrent

在这里插入图片描述

附:文本结构

高并发
	Nginx
		限制请求数
			limit_req_zone
				zone=one:10m rate=1r/s
				burst=5
		限制并发连接数
			limit_conn_zone
				perip
				perserver
	几个术语
		并行
			(真)多个任务在多条线同时进行
				如果CPU只有一个,那多进程和多线程都仅仅是并发的
		并发
			一条线交替进行多个任务,只是看起来像是同时进行多个任务(假)
			并发等级
				阻塞
					排队
					悲观
				无饥饿
					公平、不受优先级影响,先到先得
					阻塞
				无障碍
					大家同时执行,冲突出错了就回滚
					乐观
						依赖一个“一致性标志”
						1、在操作之前读取并保存这个标志;
						2、操作中,如果有修改操作要再次读取这个标志,对比是否发生了变化;
							变化了
								3、不进行修改
							没变化
								3、改变这个标志
								4、修改操作
					最弱的非阻塞
				无锁
					前提是至少一个线程能在有限步内完成操作离开临界区
						否则所有线程都会一直等待
					运气不好,会出现类似饥饿问题,比如个别线程会一直等待
					while (!atomicVar.compareAndSet(localVar, localVar+1)) {
					      localVar = atomicVar.get();
					}
						无限循环,直到本地值跟实际值相同
						本地=实际时,修改实际值
					do
						开始修改、写入等操作
				无等待
					前提是所有线程都必须在有限步内完成
						这样就不会出现饥饿问题
					典型的无等待
						Read Copy Update
							只修改原始数据的副本
								(读可以不加控制的原因)
							修改后,在合适的时机回写数据
		JMM
			Java 内存 模型
				原子性
				可见性
				有序性
		同步
			等着返回结果才继续
		异步
			任务在另一个线程中执行,不影响调用者继续干自己的事
		多进程
			一个程序至少有一个进程
			一个进程至少有一个线程
		多线程
			系统分配执行线程的cpu,可能在同一个核心,也可能在多个核心
		临界区
			公共资源、公共数据
				一旦临界资源被一个线程占用,那其他线程要使用它就就必须等待
					打印机
					写文件
		锁
			分类
				乐观锁/悲观锁
					乐观锁
						实现
							每次读数据都认为别人不会修改,所以不会上锁,只有在写的时候会判断下别人有没有修改过
							使用版本号等机制
						适用场景
							读多的场景,提高吞吐量
						实例
							java.util.concurrent.atomic下的原子变量类
								使用了CAS(比较并交换)实现
								写入时,比较内存最新版本和预期版本,一致则写入新值(同时内存版本+1)
					悲观锁
						实现
							每次读数据都认为别人会修改,所以总是上锁,这样别人读数据需要阻塞等待直到拿到锁
						适用场景
							写多的场景
						实例
							Synchronized关键字的实现就是悲观锁
				独享锁/共享锁
					独享锁
						该锁一次只能被一个线程持有
						实例
							可重入锁
							Synchronized
					共享锁
						该锁可被多个线程锁持有
						并发读更高效,但读写、写读、写写的过程是互斥的
						实例
							读写锁的读锁是共享锁,写锁是独享锁
				互斥锁/读写锁
					独享、共享是广义的说法
					互斥、读写是具体实现
						互斥锁
							ReentrantLock
								可重入锁可通过构造方法指定是否为公平锁,默认是非公平锁
						读写锁
							ReadWriteLock
				公平锁/非公平锁
					公平锁
						先申请的先得即公平
					非公平锁
						不保证先到先得,吞吐量比公平锁更大
							可重入锁可通过构造方法指定是否为公平锁,默认是非公平锁
						但可能会造成优先级反转或者饥饿现象
				可重入锁
					又名《递归锁》
					比Synchronize更强大
						增加了
							轮询
							超时
							中断
							...高级功能
					是独享锁
					是互斥锁
					是悲观锁
					可重入锁可通过构造方法指定是否为公平锁,默认是非公平锁
				分段锁
					分段锁是锁的一种实现形式
					ConcurrentHashMap就是通过分段锁的形式来实现高效的并发操作
						Put的时候,先通过hashcode来知道她要放在哪一个分段中,然后对这个分段加锁
							所以在多线程put的时候,只要不是放在同一个分段中,就实现了真正的并行的插入
				自旋锁
					尝试获取锁的线程不会立即阻塞,而是会采用循环的方式去尝试获取锁
					优点
						减少线程上下文切换的消耗
					缺点
						循环消耗cpu
				偏向锁/轻量级锁/重量级锁
					偏向锁
						如果一段同步代码一直被一个线程访问,那该线程会自动获取锁
							降低获取锁的代价
					轻量级锁
						当锁是偏向锁时,被另一个线程访问,就会升级为轻量级锁,其他线程会通过自旋的形式去获取锁
					重量级锁
						当锁是轻量级锁时,自旋不会一直持续下去,当自旋一定次数时,还没获取到锁,就会进入阻塞,该锁膨胀为重量级锁
	JUC并发编程工具包
		java.util.concurrent
			五大方面
				锁
					locks
						ReentrantReadWriteLock
							实现了读写锁(ReadWriteLock)
								ReadLock
								WriteLock
							实现了可重入锁(ReentrantLock)
							不提供加锁服务,只提供锁
								获取锁的方法
									ReentrantReadWriteLock.readLock()
									ReentrantReadWriteLock.writeLock()
						StampedLock
							三个模式
								独享写
								悲观读
								乐观读
						LockSupport
							是一个线程工具类
							静态工具类
							所有方法都是静态的
							方法
								park
									用于阻塞当前线程
								unpark
									用于唤醒被阻塞的线程
						Condition
						Lock
				原子变量
					atomic
						AtomicInteger
							get()
								获得当前值
							getAndXxx()
								获得操作前的值并进行Xxx操作
							XxxAndGet()
								Xxx操作并获得操作后的值
							compareAndSet(expect, update)
								和期望值相等则更新为update值,并返回true
								不等则不更新
								并且返回true/false
						AtomicReference
							让引用到处可见,并保持原子性
						AtomicLong
						AtomicBoolean
						AtomicArray
						DoubleAdder
							分头计算,最后汇总,参考mapreduce思想
						LongAccumulator
							比LongAdder功能强大
							可自定义计算规则
				并发框架
					Executor
						三大件
							工作单元
								Runnable
									不关注执行结果(不返回)
								Callable
									关注执行结果(有返回)
							工作单元执行
								Executor
									一个接口,定义了execute方法
								ExecutorService
									Executor的子接口,定义了一系列线程池的基本操作接口
										execute(Runnable)
										submit(Callable or Runnable)
										shutdown
											关闭新的外部任务提交
										shutdownNow
											尝试中断正在执行的所有任务
										isTerminated
											是否所有任务已经关闭
										isShutdown
											是否该ExecutorService已被关闭
										invokeAll(List<C or R>)
									有很多实现子类
							工作单元执行结果
								Future
									定义了对任务执行结果的取消、状态查询、结果获取方法
										cancel
										isCanceled
										isDone
										get
									是接口
								FutureTask
									Future的唯一实现类
						其他
							Executors
								用于快速创建各类线程池
									ScheduledExecutorService
										定长的线程池
										支持定时或周期性执行
									FixedExecutorService
										定长的线程池
										防止线程滥用
									CachedExecutorService
										可灵活伸缩线程数
										没有空闲线程回收,则创建新线程,有则回收再利用
									SingleExecutorService
										单线程的线程池
										可指定执行顺序
											FIFO
											LIFO
											优先级
					ForkJoin
						三大件
							执行任务的线程池
								ForkJoinPool
									方法
										ForkJoinTask<T> = pool.submit(forkJoinTask)
									创建方式
										new ForkJoinPool()
											使用可用的处理器数量
										ForkJoinPool.commonPool()
											最大化使用全局系统资源
							线程池中具体执行任务的线程
								ForkJoinWorkerThread
									由ForkJoinPool内部自行创建维护,不需显式地使用此类
							运行在线程池中的任务
								ForkJoinTask
									抽象类
									定义了主要操作接口
										fork
										join
										invoke
									主要实现
										RecursiveAction
											不关心结果
										RecursiveTask
											关心结果
				并发容器
					collections
						ConcurrentHashMap
							对HashMap的升级
							采用分段锁,提高了并发度
								相比synchronize HashMap的全局加锁更加高效
							读写都加锁
							在多线程中使用可不用再自己实现任何并发控制
						CopyOnWriteArrayList
							适合读多写少的场景
							拷贝写列表
							写数据时,先拷贝一个副本,再写入副本
								多份写同时进行,只保留一个结果,因此有一定风险
							读不加锁
								提高读效率
						LinkedBlockingQueue
							阻塞队列
							方法
								插入操作
									add
										立即返回
										成功=true
										无空间时则抛出:illegalStateException
									offer
										立即返回
										成功=true
										无空间时=false
										可指定超时时间,超时=false
									put
										无空间时阻塞等待,直至插入成功
								取出操作
									poll
										可指定超时时间
										获取并移除队首元素
										超时无元素返回则返回null
									take
										获取并移除队首元素,没有元素则等待
						ConcurrentLinkQueue
						ConcurrentSkipListMap
				同步工具
					tools
						Semaphore
							信号量(许可证管理工具)
								用于限制同时访问资源的线程数
							方法
								acquire
									申请许可
									可定义申请数量
									阻塞方法
										申请不到时会一直阻塞,因此申请数量不能大于许可证总数
								tryAcquire
									申请许可,并立刻返回结果
									不阻塞
									可定义申请数量
									可定义超时时间
								release
									释放许可
							和Synchronize的区别
								前者可控制一个或多个并发
								许可数为1的时候,两者无区别
						CountDownLatch
							同步计数器
								可用于监听多线程的执行情况
								可用于分头处理任务,最后总结处理
							方法
								countDown
									计数器减一
								await
									阻塞到计数为0,才被唤醒执行
									也可设置超时时间,到时间了计数不为0也可以继续往下执行
						CyclicBarrier
							循环栅栏(循环屏障)
								类似同步计数器
								所有线程都释放了对这个屏障的使用后,可重复使用这个屏障
							方法
								CyclicBarrier (int parties)
									仅指定并发数,不指定动作
								CyclicBarrier (int parties, Runnable barrierAction)
									指定次数达成后,执行某个指定动作
								await
									等待指定次数达成后才被唤醒
									也可指定超时时间
						Phaser
							移相器
								更倾向重用的循环栅栏
							方法
								register
									注册一个同步者
								arriveAndAwaitAdvance
									到达并提前等待
								arriveAndDeregister
									到达并取消注册
								getRegisteredParties
									获得注册的同步者数量
								forceTermination
									强制终止phase,phase对象不再可用
						Exchanger
							交换者
								一对线程到达同步点时,可进行数据交换
							方法
								Object v2 = exchange(Object v1)
									交出V1,得到对方的v2
									一手交钱一手交货
								可定义超时时间
	并发控制
		几个操作
			新建 
				继承Thread,重写run接口
				实现Runnable的run接口
			运行
				start
			停止
				使用stopme标志
			中断
				interrupt
			等待
				对synchronize资源有效
				线程进入等待区
			唤醒通知
				notify
					随机唤醒一个等待的线程
						不公平
				notifyAll
					唤醒全部等待的线程
						推荐
			挂起和继续执行
				suspend
					不会释放资源
				resume
					继续
				早已废弃
					不推荐
			等待线程结束
				targetThread.join()
					当前线程会等待目标线程之行结束,再往下执行
				targetThread.join(long mills)
					指定最多等待的时间,如果等不及了就不等了,继续往下执行
			谦让
				yield
					让出cpu资源一瞬间,重新跟其他线程竞争
					可以在做完重要的事后谦让,也可以让不太重要的或者优先级低的线程,多谦让谦让
		volatile
			设置变量可见性
				让多线程能够看见变量被修改后的值
		线程组
			给Thread类一个组名,提供可读性
				例如Thread-0==》WorkerThread-0
		Daemon守护线程
			如果程序没有用户线程在运行,就会退出
			JIT线程
			GC线程
			普通线程t.setDaemon(true)
				将线程t设置为守护线程,而不是用户线程,那其他线程都结束后,此线程也将被结束。
		优先级
			setPriority(1~10)
				优先级越大越优先
		synchronized
			本质只有两种级别
				对象级别
					对实例加锁
					对方法加锁
					对代码块加锁
				类级别
					对class加锁
					对静态方法加锁
		增强版锁
			重入锁
				ReentrantLock
					Re- Entrant-Lock
				显性、更加灵活
				增加了轮询、超时、中断等高级功能
				需要自行加锁,解锁
				可配置多个锁
				可用于解决死循环
				lock()
					获得锁,如果被占用则等待
				unlock()
					释放锁
				tryLock()
					不等待,没获得锁就立即返回false
				tryLock(long,TimeUnit)
					等待一定的时间,如果没等到就可以返回超时失败了
				构造方法(true)
					设置为公平锁
				Condition条件
					lock.newCondition
					await()
						类似wait
					signal()
						类似notify
					signalAll()
						类似notifyAll
					应用
						并发容器
							ConcurrentHashMap
								高效的线程安全的HashMap
							ConcurrentSkipListMap
								跳表、快速查找
							BlockingQueue
								一个接口
								阻塞队列
							ArrayBlockingQueue
								满了就等待take
								空了就等待put
							ConcurrentLinkedQueue
								线程安全的LinkedList
							ConcurrentLinkedQueue
							CopyOnWriteArrayList
								多读少写的场景,性能好于Vector
			读写分离锁
				ReentrantReadWriteLock
					readLock()
					writeLock()
				读读不阻塞
				读写阻塞
				写读阻塞
				写写阻塞
			倒数等待锁
				new CountDownLatch(10)
					countDown()
						倒数一次
					await()
						等待倒数完成
			循环栅栏(重复利用的倒数等待锁)
				CyclicBarrier
			线程阻塞工具类
				LockSupport
					park()
					unpark()
				比suspend和resume更安全
		不可变对象
			Integer
			String
			如果对不可变对象加锁,那将无效,因为不可变对象的值变化其实意味着此对象变成了新的对象,而线程看不到
			因此加锁的对象要慎重
		线程池
			更高效
			ThreadPoolExecutor
				Executors.newFixedThreadPool(32)
			用完回归再利用,不需要重新new Thread
			fixedThreadPool可防止线程滥用
			线程池有队列等待区,新提交的任务如果没有资源则会排队等待
				LinkedBlockingQueue
				SynchronousQueue
					超出制定最大值会拒绝
					不保存等待队列
					不超出如果没有空闲则会来一个创建一个线程
			自定义线程池
				实现ThreadFactory
			Nthreads = Ncpu * Ucpu * ( 1 + W/C )
				Nthreads
					最优线程池大小
				Ncpu
					cpu数量
						Runtime.getRuntime().availableProcessors()
				Ucpu
					目标cpu的利用率
						比如想要利用50%的cpu数目
				W/C
					等待时间/计算时间
	Netty
		异步的
		高性能
		高可靠性
		网络应用程序框架和工具
			开发快速
			开发简单
		用途
			大容量传输文件
			聊天
		高并发
			NIO非阻塞传输
				阻塞业务处理
				不阻塞数据接收
		传输快
			零拷贝
				不经过缓冲区,而是直接进内存
		封装好
			代码封装好,功能完备
	五种IO
		阻塞IO(BIO)
			适合连接少的场景
			延迟最低
		非阻塞IO(NIO)
			适合高并发、处理简单的场景
			接收同步,处理异步
		多路复用IO
			一个连接,接收和处理数据使用的可能是两个线程
		信号驱动IO
			主要用于嵌入式开发
		异步IO
			适合高并发、长连接的场景
			接收和处理都是异步的
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值