1. 并发编程背景及目的 :
1.1 背景 :科技发展日新月异,计算机也已发展出多cpu、多核的高计算能力的硬件,一个cpu甚至可以达到8个内核。为了将计算机的这种多核多cpu计算能力发挥到极致,以提升性能,催生了并发编程的趋势。
1.2 目的 :
1.2.1 充分利用多cpu多核的计算机计算能力
1.2.2 编发编程可以用于业务拆分,提升业务应用性能
2. 并发编程缺点 :
2.1 频繁的上下文切换,带来的性能损耗
2.1.1 同一个cpu下的多线程是通过cpu对时间片的不断切换实现,由于cpu切换较快,让我们觉得线程都是同时执行的。实际多线程同时执行一定是发生在多cpu调度下。cpu每次切换线程时需要将当前线程的状态保存起来,以便能够对之前的线程进行恢复,而这个切换是很损耗性能的,过于频繁则无法更好的发挥多线程的优势。
目前减小剩下文频繁切换的主要策略 :
无锁并发编程:可以参照concurrentHashMap锁分段的思想,不同的线程处理不同段的数据,这样在多线程竞争的条件下,可以减少上下文切换的时间。
CAS算法,利用Atomic下使用CAS算法来更新数据,使用了乐观锁,可以有效的减少一部分不必要的锁竞争带来的上下文切换
使用最少线程:避免创建不需要的线程,比如任务很少,但是创建了很多的线程,这样会造成大量的线程都处于等待状态
协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换
2.2 临界资源的线程安全问题
- 临界资源的多线程竞争访问如果不做并发控制,会造成不可预期的结果。另外多线程的竞争会造成程序死锁,从而导致系统功能的不可用。
3. 基础概念
3.1 同步VS异步
同步和异步通常用来形容一次方法调用。同步方法调用一开始,调用者必须等待被调用的方法结束后,调用者后面的代码才能执行。而异步调用,指的是,调用者不用管被调用方法是否完成,都会继续执行后面的代码,当被调用的方法完成后会通知调用者。比如,在超时购物,如果一件物品没了,你得等仓库人员跟你调货,直到仓库人员跟你把货物送过来,你才能继续去收银台付款,这就类似同步调用。而异步调用了,就像网购,你在网上付款下单后,什么事就不用管了,该干嘛就干嘛去了,当货物到达后你收到通知去取就好。
3.2 并发与并行
并发和并行是十分容易混淆的概念。并发指的是多个任务交替进行,而并行则是指真正意义上的“同时进行”。实际上,如果系统内只有一个CPU,而使用多线程时,那么真实系统环境下不能并行,只能通过切换时间片的方式交替进行,而成为并发执行任务。真正的并行也只能出现在拥有多个CPU的系统中。
3.3 阻塞和非阻塞
阻塞和非阻塞通常用来形容多线程间的相互影响,比如一个线程占有了临界区资源,那么其他线程需要这个资源就必须进行等待该资源的释放,会导致等待的线程挂起,这种情况就是阻塞,而非阻塞就恰好相反,它强调没有一个线程可以阻塞其他线程,所有的线程都会尝试地往前运行。
3.4 临界区
临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但是每个线程使用时,一旦临界区资源被一个线程占有,那么其他线程必须等待。
以上为个人学习过程中的笔记记录,温故知新。
参考文章 : https://github.com/CL0610/Java-concurrency/blob/master/1.%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9.md |