Java并发编程——基本概念
同步和异步
- 同步:对于同步调用,在这条时间轴上,会等待被调用方法的返回;
- 异步:调用和执行不是一条时间轴,只管调用,调用完后可以继续干别的事情,至于执行交给别的线程或操作系统来执行。
临界区
临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但每一次只能有一个线程使用它,一旦临界区资源被占用,其他线程想要使用这个资源,就必须等待。
阻塞和非阻塞
通常用来性容多线程间的相互影响;
- 阻塞:一个线程占用了临界区资源,那么其他所有需要这个资源的线程就必须在这个临界区进行等待,导致线程挂起,这种情况就是阻塞;
- 非阻塞:允许多个线程同时进入临界区;
死锁、饥饿和活锁
- 死锁:多个线程都占用一部分执行所需要的资源,互相等待彼此占用的资源,又不释放自己所占用的资源;
- 饥饿:一个线程长时间得不到处理器执行,处于饥饿状态;
- 活锁:类似于电梯遇人事情,假设有线程A和线程B,线程A占用一半资源a,线程B占用一半资源b,当有竞争发生时,线程A释放占用资源,线程B也释放占用资源。这时线程A又获取到b资源,线程B又获取到a资源。就这样来回交换资源,却一直得不到执行的状态就是活锁;
并发级别
- 阻塞:当一个线程进入临界区后,其他线程必须等待;(可以认为是一种悲观的阻塞策略,他认为如果多个线程一起修改临界区数据,会出现线程安全问题,所以一旦出现多个进程访问临界区它就会阻塞)
- 无障碍(Obstrction-Free):(认为是一种比较乐观的策略,它认为就算是多个线程进入临界区也不一定会把出现安全问题,所以可以有多个线程进入临界区,它遵循一种宽进严出的原则,如果在临界区中一旦发生了竞争现象则回滚数据,线程回滚后再重试,直到读取到正确的数据。)如果线程之间是彼此干扰的,会导致最后所有的线程都卡死在里面;
- 无障碍是一种最弱的非阻塞调度;
- *出入临界区;
- 无竞争时,有限步内完成操作;
- 有竞争时,回滚数据;
- 无锁(Lock-Free):
- 是无障碍的;(保证有多个线程能进入临界区)
- 保证有一个线程是必然能够胜出;
- 无等待(Wait-Free):
- 无锁的;(保证有多个线程能进入临界区,并且至少有一个线程可以顺利执行完成)
- 要求所有线程都必须在有限步内完成;
- 无饥饿的;
2个重要定律
- Andahl定律(阿姆达尔定律)
- 定义了串行系统并行化后的加速比的计算懂事和理论上限;
- 加速比定义:加速比=优化前系统耗时/优化后系统耗时;
- Gustafson定律(古斯塔夫森)
说明处理器个数,串行比例和加速比之间的关系;
使用线程的原因?
使用线程的原因是因为进程的创建、销毁、切换等方面都是非常重量级的,需要的系统的开销特别大。但又要保证并发执行的方式,所以使用了开销小的线程。
在Java当中创建一个线程就等于是在操作系统中创建一个线程;