线程与并发基础

01 线程与并发基础

线程概念

线程: 线程是CPU分配的基本单位

进程 : 进程是进行资源分配和调度的基本单位。

进程与线程关系:线程是进程的一个执行路径 ,一个进程中至少包含一个线程,进程中的多个线程共享进程中的资源。

同步和异步

同步异步 通常用来形容一次方法调用。

同步: 同步方法一旦调用开始,调用者必须等到方法调用返回后,才能继续后续的行为。

异步: 异步方法调用更像一个消息传递,一旦开始,方法调用会立即返回,调用者才能继续后续操作。异常方法通常会在另外一个线程中执行。

临界区

临界区 :临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用,但是每一次,都只能有一个线程来使用它,一旦临界资源被占用,其他线程想要使用这个资源,就必须进行等待。在并行程序中,临界资源是需要保护的资源。

线程定义

多线程间的相互影响

线程阻塞(Blocking) : 一个线程占用了临界区的资源,那么其他所有需要这个资源的线程就必须在这个临界区中等待。等待会导致线程挂起,这种情况被称为线程阻塞。如果占用资源的线程一直不愿意释放资源,那么其他阻塞在这个临界区的线程都不能工作。

线程非阻塞(Non-Blocking) :没有一个线程可以妨碍其他线程的执行。所有的线程都会尝试不断执行。

多线程的活跃性

如果出现死锁、饥饿、活锁中的任何一种,那么线程可能就不再活跃了,很难执行下去了。

线程死锁(DeadLock) : 线程死锁是指两个或两个以上的线程互相持有对方所需要的资源,由于synchronized的特性,一个线程持有一个资源,或者说获得一个锁,在该线程释放这个锁之前,其它线程是获取不到这个锁的,而且会一直死等下去,因此这便造成了死锁。

线程饥饿(Starvation) : 饥饿是指某一个或者多个线程由于种种原因无法获得所需要的资源,导致一直无法执行。

情况一 :例如它的线程优先级可能非常低,而高优先级的线程不断抢占它需要的资源,导致低优先级的工作无法执行。

情况二 :某一个线程一直占着关键资源不放手,导致其他需要这个资源的线程无法执行,这种情况也是线程饥饿的一种。

线程饥饿还是有可能在未来的某一段时间内解决的。比如高优先级的线程已经执行完,不再疯狂的创建线程。

线程活锁(LiveLock) :是指多个线程秉承着”谦让的”原则,主动将资源释放给其他人使用,那么就会出现资源在两个线程中不断的跳动,而没有一个线程可以同时拿到所有的资源而正常执行。这种情况就是活锁

并发级别

由于临界区的存在,多线程之间的并发控制必须受到控制。并发的级别分为五大类。阻塞无饥饿无障碍无锁无等待

阻塞 : 一个线程是阻塞的,那么其他线程释放资源之前,当前线程无法继续执行。当我们使用synchronized关键字或者重入锁的时候,我们得到的就是阻塞的线程。

无饥饿 :如果线程之间是有优先级的,那么线程的调用总是会倾向于高优先级的线程。也就是说,对于一个资源的分配是不公平的。对于非公平的锁来说,系统允许高优先级的线程插队。这样有可能导致低优先级的线程产生饥饿 .但是如果锁是公平的,那么饥饿就不会产生,不管新来的线程优先级有多高,要想获取到资源,就必须排队,所有的线程都会有机会执行。