1.1讲解了什么是同步和异步,指出,同步异步指的是一次方法的调用
同步:指的是调用者必须等到方法执行完之后得到返回之后才能继续执行
异步:指的是调用者无需等到方法执行完之后执行,异步方法会在另一个线程中执行,整个过程不会影响到调用者的执行,
如果调用者需要返回值,那么等到这个异步调用完成之后。
1.2 什么是并发,什么是并行,这有什么区别?
首先并发和并行都可以表示多个任务在一起执行,但是其侧重点各不相同,并发指的是任务交替进行,多个任务之间还有可能是串行的
而并行则是真正意义上的"同时执行"。严格意义上来说,并行是多个任务同时执行,而并发则是在这个过程是交替执行的,一会运行任务A
一会运行任务B....系统不停地来回切换。但是对于外部的观察者来说,即使是多个任务串行并发的,也造成了同时执行的错觉。
1.3临界区
临界区表示一种公共资源或者共享数据,但是每次只能有一个线程可以使用它,一旦临界区的资源被占用,其他线程只能等待,否则可能会
破坏数据
1.4 阻塞和非阻塞
阻塞和非阻塞通常用来表示多线程的相互影响,比如一个线程占用了临界区的资源,这个时候其他想要使用该临界区的线程就只能等待,等待会使该线程被挂起,这种情况就是阻塞,此时如果该线程始终不愿意释放资源,则其他阻塞的线程就一直不能正常工作,非阻塞则是在不能立刻得到结果之前,线程不会一直等待结果,还是以逛淘宝为例,在等待客服回复时,阻塞相当于你的精力一直放在与客服聊天的页面上,客服不回复我就不走了。非阻塞就相当于你还是有一部分精力放在与客服聊天的页面上,不过同时你也可以干其他的事情(注意是可以,你也可以不干其他任何事,就坐在那里发呆)
1.5 死锁,饥饿和活锁
死锁是指两个或者两个以上的进程在执行的过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力的作用下它们都将无法推进下去,此时系统处于死锁状态,这些永远在互相等待的进程称之为死锁进程。
饥饿是指某一个线程或者多个线程由于种种原因始终得不到所需要的资源,导致一直无法执行,比如他的线程优先级太低,而高优先级的
线程不断抢占它需要的资源,导致低的优先级的线程无法工作。与死锁相比,饥饿可能会在未来的某个时间段内解决。
而活锁相对其他就显得比较有趣,秉承着“谦让”的原则,但是如果同时作用于两个线程的话就尴尬了,都主动将资源呈递给其他线程使用
那么资源就在这两个线程中来回跳动,而没有一个线程可以拿到资源而正常执行。
1.6 并发级别
由于临界区的存在,多线程之间的并发必须受到控制,大致可以分为,阻塞,无饥饿,无障碍,无锁,无等待
1.6.1 阻塞
一个线程是阻塞的,那么在其他线程释放之前,当前线程是无法继续执行,当我们使用synchronized关键字或者重入锁的时候
我们得到的就是阻塞的线程,无论是重入锁还是synchronized关键字,在执行后续的代码之前都是获得临界区的锁,如果得不到
那么线程将会被挂起,直到获取到所需要的资源为止。
1.6.2 无饥饿
如果线程之间是有优先级的,那么线程调度的时候总是优先满足于线程优先级高的线程,也就是说对于同一资源的分配,线程之间是不公平的
这样就会导致优先级低的线程饥饿,但是如果锁是公平的话,当获取临界区的资源的时候都乖乖排队,那么所有线程都有机会执行。
1.6.3 无障碍
无障碍是一种最弱的非阻塞调度,两个线程如果是无障碍的执行,那么他们不会因为临界区阻塞问题而被挂起,也就是说可以同时进入临界区,如果修改坏了数据那么回滚
1.6.4 无锁
无锁的并行都是无障碍的,在无锁的情况下,所有的线程都可以进入访问临界区,但是不同的是,无锁的并发保证是至少有一个线程在有线步骤内完成操作离开临界区