`

死锁的问题

阅读更多
1.某个任务在等待另个任务,而后者有等待别的任务,这样一直下去,直到这个链条上的任务又在等待第一个任务释放锁,这种现象就称为死锁。

2.当以下四个条件同时满足时,就会发生死锁:
(1)互斥条件:线程使用的资源中至少有一个是不能共享的。这里,一根筷子一次就只能被一个哲学家使用。
(2)至少有一个进程持有一个资源,并且它在等待获取一个当前被别的进程持有的资源。也就是说,要发生死锁,哲学家必须拿着一根筷子并且等待另一根。
(3)资源不能被进程抢占。所有的进程必须把资源释放作为普通事件。哲学家很有礼貌,他们不会从其他哲学家那里抢筷子。
(4)必须有循环等待,这时,一个进程等待其它进程持有的资源,后者又在等待另一个进程持有的资源,这样一直下去,直到有一个进程在等待第一个进程持有的资源,使得大家都被锁住。


    因为要发生死锁的话,所有这些条件必须全部满足,所以你要防止死锁的话,只需破坏其中一个即可。在程序中,防止死锁最容易的方法是破坏条件4。有这个条件的原因是每个哲学家都试图用特定的顺序拿筷子:先左后右。正因为如此,就可能会发生“每个人都拿着左边的筷子,并等待右边的筷子”的情况,这就是循环等待条件。然而,如果最后一个哲学家被初始化成先拿右边的筷子,后拿左边的筷子,那么这个哲学家将永远不会阻止其左边的哲学家拿起他/她右边的筷子,这就打破了循环等待。这只是问题的解决方法之一,你也可以通过破坏其它条件来防止死锁(具体细节请参考更高级的线程书籍)。Java对死锁并没有提供语言层面上的支持;能否通过小心的程序设计以避免死锁,取决于你自己。对于正在试图调试一个有死锁的程序的程序员来说,没有什么更好消息。


发生死锁的代码如下:
public class Chopstick {
private boolean taken = false;

public synchronized void take() throws InterruptedException {
while (taken)
wait();
taken = true;
}

public synchronized void drop() {
taken = false;
notifyAll();
}
}

public class Philosopher implements Runnable {
private Chopstick left;
private Chopstick right;
private final int id;
private final int ponderFactor;
private Random rand = new Random(47);

private void pause() throws InterruptedException {
if (ponderFactor == 0)
return;
TimeUnit.MILLISECONDS.sleep(rand.nextInt(ponderFactor * 250));
}

public Philosopher(Chopstick left, Chopstick right, int ident, int ponder) {
this.left = left;
this.right = right;
id = ident;
ponderFactor = ponder;
}

public void run() {
try {
while (!Thread.interrupted()) {
System.out.println(this + " " + "thinking");
pause();
// Philosopher becomes hungry
System.out.println(this + " " + "grabbing right");
right.take();
System.out.println(this + " " + "grabbing left");
left.take();
System.out.println(this + " " + "eating");
pause();
right.drop();
left.drop();
}
} catch (InterruptedException e) {
System.out.println(this + " " + "exiting via interrupt");
}
}

public String toString() {
return "Philosopher " + id;
}
}
public class DeadlockingDiningPhilosophers {
public static void main(String[] args) throws Exception {
int ponder = 0;

int size = 5;

ExecutorService exec = Executors.newCachedThreadPool();
Chopstick[] sticks = new Chopstick[size];
for (int i = 0; i < size; i++)
sticks[i] = new Chopstick();
for (int i = 0; i < size; i++)
exec.execute(new Philosopher(sticks[i], sticks[(i + 1) % size], i,
ponder));
TimeUnit.SECONDS.sleep(5);
System.out.println("Press 'Enter' to quit");
System.in.read();
exec.shutdownNow();
}
}

ponder 时间越小,发生死锁的概率越大

改进后的代码:
public class FixedDiningPhilosophers {
public static void main(String[] args) throws Exception {
int ponder = 0;
int size = 5;
ExecutorService exec = Executors.newCachedThreadPool();
Chopstick[] sticks = new Chopstick[size];
for (int i = 0; i < size; i++)
sticks[i] = new Chopstick();
for (int i = 0; i < size; i++)
if (i < (size - 1))
exec.execute(new Philosopher(sticks[i], sticks[i + 1], i,
ponder));
else
exec.execute(new Philosopher(sticks[0], sticks[i], i, ponder));
TimeUnit.SECONDS.sleep(5);
System.out.println("Press 'Enter' to quit");
System.in.read();
exec.shutdownNow();
}
}

主要是破坏循环等待的条件
分享到:
评论

相关推荐

    操作系统实验六 死锁问题实验

    操作系统中的死锁问题是一个复杂而重要的概念,它涉及到并发进程之间的资源分配和同步问题。死锁是指两个或多个进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉它们都将无法推进下去。这个...

    车辆行驶死锁问题

    "车辆行驶死锁问题" 车辆行驶死锁问题是指在一组进程中的各个进程占有不会释放的资源,但因互相申请被其他进程所占用不会释放的资源而处于一种永久等待的状态。本实验主要使用资源有序分配策略来预防死锁。 死锁的...

    操作系统死锁问题

    ### 操作系统中的死锁问题解析 #### 一、引言 在计算机科学领域,特别是操作系统设计中,死锁是一个非常关键且复杂的问题。当两个或多个进程在等待彼此所持有的资源时,就会形成死锁状态,导致这些进程无法继续执行...

    有关于哲学家进餐死锁问题及预防的课程设计报告

    ### 哲学家进餐死锁问题及预防的课程设计报告知识点详解 #### 一、研究目的与意义 - **目的**: 通过模拟计算机操作系统中经典的“哲学家就餐问题”,帮助学生巩固操作系统原理课程中学到的知识,特别是关于进程...

    用银行家算法预防解答死锁问题

    ### 银行家算法预防解答死锁问题 在计算机操作系统中,进程间对资源的竞争可能会导致死锁问题。死锁是指多个进程都在等待其他进程所持有的资源而无法继续执行的状态。为了解决这一问题,引入了多种算法,其中银行家...

    关于Oracle数据库死锁问题的研究与讨论

    关于Oracle数据库死锁问题的研究与讨论

    典型死锁问题.rar_操作系统典型死锁问题

    操作系统中的死锁问题一直是计算机科学领域的一个重要话题,特别是在多任务并发执行的环境中。这个问题涉及到资源分配、进程调度以及系统安全。本压缩包文件“典型死锁问题.rar”提供了三个经典的死锁示例:哲学家...

    数据库死锁-解决死锁问题的三种办法

    总之,解决数据库死锁问题的三种方法各有优缺点,实际应用中应根据具体情况和需求选择最适合的策略。预防死锁虽能有效避免死锁的发生,但可能限制了资源的利用率;检测死锁虽然灵活性较高,但可能会增加系统的复杂性...

    db2死锁问题分析及解决方案

    ### DB2死锁问题分析及解决方案 #### 一、引言 在数据库管理与维护过程中,死锁问题是一个常见的挑战,特别是在使用IBM DB2这样的大型关系型数据库管理系统时。本文将详细探讨DB2中死锁问题的分析方法及有效的解决...

    实验六、 死锁问题实验

    在两个城市南北方向之间存在一条铁路,多列火车可以分别从两个城市的车站 排队等待进入车道向对方城市行驶,该铁路在同一时间,只能允许在同一方向上行 车,如果同时有相向的火车行驶...您能构造一个管程来解决这个问题吗?

    Java解决死锁问题eclipse代码版

    本文将深入探讨如何使用`synchronized`来解决Java中的死锁问题。 首先,我们需要理解死锁的四个必要条件: 1. 互斥条件:至少有一个资源必须在任何时候只能由一个线程使用。 2. 请求与保持条件:一个线程因请求被...

    操作系统中的死锁问题

    ### 操作系统中的死锁问题 #### 死锁概述 在多道程序设计技术被引入到操作系统之后,程序并发执行成为常态,同时也带来了一系列的新挑战,其中之一便是“死锁”。死锁是指两个或多个进程在执行过程中因争夺资源而...

    在SQL Server 2005中解决死锁问题

    SQL Server 2005引入了新的处理机制,使得开发者可以通过T-SQL捕获并处理这些异常,从而更有效地解决死锁问题。 在SQL Server 2000中,当事务遇到异常,如死锁,T-SQL脚本会立即停止执行,使得对死锁的处理变得困难...

    多线程死锁问题

    本篇文章将深入探讨Java中的死锁问题,并通过提供的代码示例`ProducerConsumer.java`、`TestDeadLock.java`和`Count3Quit.java`来解释如何识别和解决死锁。 首先,我们需要理解死锁的四个必要条件: 1. **互斥**:...

    操作系统银行家算法避免进程死锁问题

    安全性算法,银行家算法,避免进程死锁的问题,这是我用C语言编的程序,运行通过。

    db2死锁问题.doc

    ### DB2死锁问题解析与处理方法 #### 一、理解DB2死锁现象 **DB2**(DB2 Universal Database)是由IBM公司开发的一款关系型数据库管理系统。在多用户并发访问DB2数据库的过程中,可能会遇到所谓的“死锁”问题。...

    HIS系统SQL Server数据库死锁问题的分析与解决.pdf

    HIS系统SQL Server数据库死锁问题的分析与解决 SQL Server数据库是HIS系统中非常重要的一部分,负责存储和管理大量的医疗数据。然而,在实际应用中,SQL Server数据库可能会出现死锁问题,导致系统性能下降, thậm...

    山东大学操作系统实验6死锁问题

    这个实验,"山东大学操作系统实验6——死锁问题",显然是为了让学生深入理解死锁的发生机制以及解决策略。 死锁的四个必要条件包括互斥、占有并等待、非剥夺和循环等待。在操作系统中,资源可能是独占式的,如CPU...

    mysql innodb死锁问题详解.docx

    MySQL的InnoDB存储引擎在处理并发事务时可能会遇到死锁问题,这主要发生在多个事务互相等待对方释放资源的情况下。死锁通常由四个必要条件引发: 1. 互斥条件:资源只能被一个事务使用。 2. 请求和保持条件:一个...

    哲学家就餐问题与死锁问题

    操作系统死锁问题 C语言实现 有详细代码 都能实现

Global site tag (gtag.js) - Google Analytics