RT代码如下:
public class AnotherDeadLock {
public static void main(String[] args) {
final Object resource1 = "resource1";
final Object resource2 = "resource2";
// t1 tries to lock resource1 then resource2
Thread t1 = new Thread() {
public void run() {
// Lock resource 1
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
synchronized (resource2) {
System.out.println("Thread 1: locked resource 2");
}
}
}
};
// t2 tries to lock resource2 then resource1
Thread t2 = new Thread() {
public void run() {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
synchronized (resource1) {
System.out.println("Thread 2: locked resource 1");
}
}
}
};
// If all goes as planned, deadlock will occur,
// and the program will never exit.
t1.start();
t2.start();
}
}
各位可以自己试一试,有点儿疑惑(因为老师上课讲的是死锁会引发系统资源居高不下),
然后在德问社区中发帖求助,有大神回答如下:
源:http://www.dewen.org/q/13297/%E7%BA%BF%E7%A8%8B%E6%AD%BB%E9%94%81%E6%98%AF%E4%B8%8D%E6%98%AFcpu%E8%B5%84%E6%BA%90%E4%B8%80%E5%AE%9A%E4%BC%9A%E5%B1%85%E9%AB%98%E4%B8%8D%E4%B8%8B#24104
这取决于锁的实现,通常锁有两种实现:
-
拿不到锁的时候,忙等待,反复探测锁状态,直到拿到锁,进入临界区。这种情况会消耗CPU。
这种锁,称为自旋锁。比如pthread_spin_lock。
-
拿不到锁的时候,放弃CPU,休眠,离开运行队列,这种情况不会消耗CPU。
这种锁,称为休眠锁。pthread_mutex就是这种锁。也是最常用的锁。
当然通常不会直接使用sleep实现,因为sleep会导致 释放锁后,等锁的线程不能及时醒来干活儿。一般会借助系统调用,比如linux上会使用futex,这个调用可以让等锁线程休眠直到被释放锁的线程唤醒 它。等锁线程会执行FUTEX_WAIT休眠, 而unlock的线程会执行FUTEX_WAKE唤醒休眠的等锁线程。
很显然由于自旋锁不会放弃CPU,没有调度开销(进出运行队列),性能要好于休眠锁,只是等锁的时候CPU是100%,所以适用于临界区比较短的场景。
facebook的folly库,实现了一种混合的锁,先自旋一定的次数,然后执行sleep放弃cpu。可以避免异常情况下,持锁进程长时间不释放导致的CPU开销问题。
关于锁的更多的探讨,可以参考我的一篇博文《多核环境下锁优化方法分析》
java的synchronized应该是休眠锁。所以不占CPU。
另外打大神:
恰恰相反, 死锁的线程基本上不占用cpu. 你试一下自己的程序就知道了.
更新
因为你用java来举例, 而根据经验, java死锁的时候, cpu很低(不考虑有别的线程占用cpu的情况).
sun java1.7 x64:
死锁的线程:
- "Thread-1" prio=6 tid=0x0000000009184800 nid=0xd64 waiting for monitor entry [0x000000000b2ef000]
- java.lang.Thread.State: BLOCKED (on object monitor)
- at AnotherDeadLock$2.run(AnotherDeadLock.java:35)
- - waiting to lock<0x00000000ecdc2020>(a java.lang.String)
- - locked <0x00000000ecdc1fc8>(a java.lang.String)
- Locked ownable synchronizers:
- -None
- "Thread-0" prio=6 tid=0x0000000009184000 nid=0x1618 waiting for monitor entry [0x000000000b0ff000]
- java.lang.Thread.State: BLOCKED (on object monitor)
- at AnotherDeadLock$1.run(AnotherDeadLock.java:17)
- - waiting to lock<0x00000000ecdc1fc8>(a java.lang.String)
- - locked <0x00000000ecdc2020>(a java.lang.String)
- Locked ownable synchronizers:
- -None
死锁线程不占cpu:
大神回答:
进程的死锁是由两个以上的进程并发互斥访问临界资源时,发生相互等待造成的,进入死锁后,除了已经使用的资源外,并未有使用包括内存,CPU时间片等计算机资源。这是操作系统常识。
看来老师上课讲的不全是对的了
相关推荐
理解并解决死锁是Java开发者必须掌握的关键技能之一,尤其是在构建高并发、多线程系统时。 死锁的四个必要条件: 1. 互斥条件:至少有一个资源必须处于独占状态,即一次只有一个线程能使用。 2. 请求与保持条件:...
为了模拟死锁,我们使用 synchronized 块来锁住这两个资源,并在锁住的过程中进行 sleep 操作,以便模拟资源的占用。 5. synchronized 块的使用:在 Java 中,synchronized 块可以用来锁住一个对象,以便实现线程...
Java线程死锁是多线程编程中一个重要的概念,它发生在两个或多个线程互相等待对方释放资源,导致它们都无法继续执行的情况。死锁的理解和预防对于编写高并发、高性能的Java应用至关重要。 首先,我们需要了解线程的...
避免死锁是 Java 编程中的一个重要任务,因为死锁可能会导致系统功能不可用。下面我们将讨论避免死锁的常见方法。 避免一个线程同时获取多个锁 在 Java 中,死锁通常是由于线程在索内同时占用多个资源引起的。为了...
在Java面向对象程序设计中,并发处理是提升系统性能的关键技术之一,特别是在农业信息系统开发这样的领域,高效的数据处理和分析往往需要多线程环境来实现。然而,并发执行也带来了死锁的问题,这是多线程编程中必须...
在数据库系统中,当两个或多个事务在等待对方释放资源时就会发生死锁。这种情况类似于现实生活中的两个或多个人互相等待对方做出动作而自己却不动的情况。具体到数据库环境中,如果事务A已经锁定了一部分数据并请求...
在数据库管理中,死锁是常见的问题之一,特别是在并发环境中,比如SQLite这样的嵌入式数据库。当两个或多个事务在执行过程中,互相等待对方释放资源,导致无法继续进行时,就发生了死锁。"database is locked"错误是...
如果存在,说明分配资源不会导致死锁,可以进行分配;如果不存在,则拒绝请求。 4. 分配资源:如果安全序列存在,更新已分配资源,并减少可用资源。 5. 释放资源:当进程完成或因资源不足而终止时,释放其占用的资源...
4. 循环等待条件:在发生死锁时,必然存在一个进程-资源的环形链,即进程集合{P1, P2, ..., Pn}中的P1正在等待P2所占用的资源,P2等待P3占用的资源,依此类推,直到Pn等待P1占用的资源。 避免死锁的方法主要有以下...
5. **并发不当**:在多线程环境中,如果没有正确同步对资源的访问,可能会出现数据不一致或死锁等问题,影响程序的正确性。 总之,理解并遵循Java中的优良资源管理实践,同时避免不良的资源管理习惯,将有助于编写...
释放这些session同样重要,以防止它们占用资源或阻塞其他会话。通常情况下,当使用`ALTER SYSTEM KILL`命令杀死一个会话后,该会话将自动释放。然而,在某些复杂场景下,可能需要手动干预,如重新启动数据库实例或...
在Java编程中,了解程序运行时的资源占用情况对于优化性能、排查问题至关重要。这篇文章将深入探讨如何通过Java来查看程序资源的使用状况,包括内存、CPU、线程等关键指标。 首先,JConsole是Java提供的一款强大的...
操作系统是计算机科学的核心领域之一,而银行家算法则是操作系统中解决死锁预防的一种经典方法。本文将深入探讨银行家算法的原理,并结合Java语言来阐述其实现过程,以帮助读者更好地理解和应用这一理论。 银行家...
在理发师问题中,多个线程(代表顾客)可能同时访问有限的资源(如座位),这需要通过互斥锁或信号量等机制确保资源不会被同时访问,避免数据不一致或死锁等问题。在给定的代码中,`Semaphore`类被用来实现这一功能...
Java线程(JavaThread)是Java程序中执行的独立单元,它是Java多线程编程的基础。在Java中,每个应用程序至少有一个线程,通常被称为"主线程",用于执行程序的主要逻辑。Java线程允许程序同时执行多个任务,极大地...
5. 释放资源:进程完成后或因其他原因终止时,会释放其占用的所有资源,这些资源将重新加入到系统可用资源池中。 三、银行家算法的Java实现 在Java中,可以创建类来表示资源、进程、需求、分配和可用资源等概念,...
内存泄漏是程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄漏可能看似无足轻重,但随着时间推移,这些未被释放的内存会不断积累,最终可能导致系统资源耗尽。而内存溢出则是程序请求的内存超过了系统所...
Java银行家算法是操作系统领域中一种经典的资源分配策略,用于避免系统的死锁状态。它由艾兹格·迪杰斯特拉在1965年提出,主要用于解决多进程环境下资源的竞争问题,确保系统安全运行。在Java中实现银行家算法,可以...
在Java编程中,为了提升程序的性能,开发者需遵循一系列最佳实践原则,下面将详细解析这些原则及其背后的原因。 ### 1. 合理运用单例模式 单例模式是设计模式之一,确保一个类只有一个实例,并提供一个全局访问点...