进程 (线程) 同步的基本概念
进程之间的制约关系
1. 直接制约关系(进程同步)
这个关系主要源于进程合作, 例如, 有一个输入进程 A 通过单缓冲向进程 B 提供数据, 当该缓冲空时, 进程 B 因为不能获得所需数据而被阻塞, A 将数据送入缓冲区时边将 B 唤醒.
2. 间接制约关系(进程互斥)
这种关系主要源于资源共享, 比如有俩个进程 A,B 都在竞争打印机资源, 如果在 A 提出打印请求时, 系统已将打印机分配给 B, 则进程 A 进入阻塞状态, 等进程 B 释放打印机后, 才能唤醒 A
进程同步遵循的规则
1 空闲让进
当无进程进入临界区时, 相应的临界资源处于空闲状态, 因而允许一个请求进入临界区的进程立即进入自己的临界区.
2 忙则等待
当已有进程进入自己的临界区时, 即相应的临界资源正被访问, 因而其它试图进入临界区的进程必须等待, 以保证进程互斥地访问临界资源.
3 有限等待
对要求访问临界资源的进程, 应保证进程能在有限时间进入临界区, 以免陷入 "饥饿" 状态.
4 让权等待
当进程不能进入自己的临界区时, 应立即释放处理机, 以免进程陷入忙等.
死锁的概念
一. 什么是死锁?
如果一个进程集合里面的每个进程都在等待这个集合中的其他一个进程 (包括自身) 才能继续往下执行, 若无外力他们将无法推进, 这种情况就是死锁, 处于死锁状态的进程称为死锁进程
二. 死锁产生的原因?
1. 因竞争资源发生死锁 现象: 系统中供多个进程共享的资源的数目不足以满足全部进程的需要时, 就会引起对诸资源的竞争而发生死锁现象
(1)可剥夺资源和不可剥夺资源: 可剥夺资源是指某进程在获得该类资源时, 该资源同样可以被其他进程或系统剥夺, 不可剥夺资源是指当系统把该类资源分配给某个进程时, 不能强制收回, 只能在该进程使用完成后自动释放
(2)竞争不可剥夺资源: 系统中不可剥夺资源的数目不足以满足诸进程运行的要求, 则发生在运行进程中, 不同的进程因争夺这些资源陷入僵局.
举例说明: 资源 A,B; 进程 C,D
资源 A,B 都是不可剥夺资源: 一个进程申请了之后, 不能强制收回, 只能进程结束之后自动释放. 内存就是可剥夺资源
进程 C 申请了资源 A, 进程 D 申请了资源 B.
接下来 C 的操作用到资源 B,D 的资源用到资源 A. 但是 C,D 都得不到接下来的资源, 那么就引发了死锁.
(3)竞争临时资源
2. 进程推进顺序不当发生死锁
三. 产生死锁的四个必要条件?
(1)互斥条件: 进程对所分配到的资源不允许其他进程进行访问, 若其他进程访问该资源, 只能等待, 直至占有该资源的进程使用完成后释放该资源
(2)请求和保持条件: 进程获得一定的资源之后, 又对其他资源发出请求, 但是该资源可能被其他进程占有, 此事请求阻塞, 但又对自己获得的资源保持不放
(3)不可剥夺条件: 是指进程已获得的资源, 在未完成使用之前, 不可被剥夺, 只能在使用完后自己释放
(4)环路等待条件: 是指进程发生死锁后, 必然存在一个进程 -- 资源之间的环形链
四. 处理死锁的基本方法
1. 预防死锁: 通过设置一些限制条件, 去破坏产生死锁的必要条件
2. 避免死锁: 在资源分配过程中, 使用某种方法避免系统进入不安全的状态, 从而避免发生死锁
3. 检测死锁: 允许死锁的发生, 但是通过系统的检测之后, 采取一些措施, 将死锁清除掉
4. 解除死锁: 该方法与检测死锁配合使用
因为竞争资源产生死锁实例:
- class DeadLock extends Thread{
- public DeadLock(boolean sign,String str) {
- super(str);
- this.sign = sign;
- }
- private boolean sign = false;
- private static Object objA = new Object();
- private static Object objB = new Object();
- @Override
- public void run() {
- while(true){
- if(sign){
- synchronized (objA) {
- System.out.println(Thread.currentThread().getName()+"获得资源 A");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- synchronized (objB) {
- System.out.println(Thread.currentThread().getName()+"获得资源 B");
- }
- }
- }else {
- synchronized (objB) {
- System.out.println(Thread.currentThread().getName()+"获得资源 B");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- synchronized (objA) {
- System.out.println(Thread.currentThread().getName()+"获得资源 A");
- }
- }
- }
- }
- }
- }
- public class DeadLockDemo{
- public static void main(String[] args) {
- Thread t1 = new DeadLock(true,"线程一");
- Thread t2 = new DeadLock(false,"线程二");
- t1.start();
- t2.start();
- }
- }
来源: https://www.cnblogs.com/gollong/p/9388316.html