java并发的概念

1.并发的概念:

      并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

2.并行的概念:

     指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。

区别:
并发和并行的区别就很明显了。它们虽然都说是"多个进程同时运行",但是它们的"同时"不是一个概念。并行的"同时"是同一时刻可以多个进程在运行(处于running),并发的"同时"是经过上下文快速切换,使得看上去多个进程同时都在运行的现象,是一种OS欺骗用户的现象。

3.临界区

表示一种公共资源或者说是共享数据,可以被多个线程使用。

4.阻塞和非阻塞

阻塞是指一个线程占用了临界区资源,那么其他所有需要这个资源的线程就必须在这个临界区中进行等待,等待会导致挂起,这种情况就叫做阻塞。
非阻塞是指多个线程可以同时进入临界区

5.死锁,饥饿,活锁

5.1死锁

线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。
产生死锁的四个条件
1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资 源,则请求者只能等待,直至占有资源的进程用毕释放。
2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

5.2活锁

多线程中出现了相互谦让,都主动将资源释放给别的线程使用,这样资源在多个线程之间跳动而又得不到执行,形成活锁。

5.3饥饿锁

   一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行的状态。多线程中优先级高的会优先执行,并且抢占优先级低的资源,导致优先级低的线程无法得到执行。

5.4无锁

即没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。如果有多个线程修改同一个值必定会有一个线程能修改成功,而其他修改失败的线程会不断重试直到修改成功无锁(JDK的CAS)。

6.并发的级别

6.1 阻塞

一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法继续执行。比如:使用synchronize关键字或者其他重入锁,我们得到的就是阻塞的线程。无论是synchronized或者重入锁,都会在试图执行后续代码前,得到临界区的锁,如果得不到,线程就会被挂起等待,直到占有了所需资源为止。

6.2 无饥饿(Starvation-Free)

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

6.3 无障碍(Obstruction-Free)

无障碍是一种最弱的非阻塞调度。两个线程如果是无障碍的执行,那么他们不会因为临界区的问题导致一方被挂起。换言之,大家都可以大摇大摆的进入临界区了。那么如果大家一起修改共享区数据,把数据修改坏了怎么办呢?对于无障碍的线程来说,一旦检测到这种情况,它就会立即对自己所做的修改进行回滚,确保数据安全。但是如果没有数据竞争发生,那么线程就可以顺利完成自己的工作,走出临界区。

从这个策略可以看出,无障碍的多线程程序不一定能顺畅的运行。因为当临界区中存在严重的冲突时,所有的线程可能都会不断的回滚自己的操作,导致没有一个线程能顺利走出临界区。这种情况会影响系统的正常执行。

一种可行的无障碍实现可以依赖一个“一致性标记”来实现:线程在操作之前,先读取并保存这个标记,在操作完成之后,再次读取,检查这个标记是否更改过,如果两者是一致的,则说明资源访问没有冲突。如果不一致,则说明资源可能在操作过程中与其他线程存在冲突,需要重新操作。而任何对资源有修改操作的线程,在修改数据前,都需要更新这个一致性的标记,表示数据不再安全。

6.4 无锁(Lock-Free)

无锁的并行都是无障碍的。在无锁的情况下,所有的线程都能尝试对临界区进行访问,但不同的是,无锁的并发保证必然有一个线程能够在有限步内完成操作走出临界区。

在无锁的调用中,一个典型的特点是可能会包含一个无限循环。在这个循环中,线程会不断尝试修改共享变量,如果没有冲突,修改成功,那么程序退出。否则继续尝试修改,但无论如何,无锁的并行总能保证一个线程胜出,不会全军覆没。至于临界区中竞争失败的线程,它们则必须不断重试,直到自己获胜,如果运气不好,总是不成功,则会出现饥饿的现象,线程会停止不前。

6.5 无等待(Wait-Free)

无锁只要求一个线程可以在有限步数内完成操作,而无等待则是在无锁的基础上更进一步进行扩展,它要求所有的线程都必须在有限步数内完成,这样就不会引起线程饥饿问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值