转: http://blog.csdn.net/xiaoya629/archive/2010/04/23/5519538.aspx
当synchronized使用过多时,可能会造成死锁,那么死锁到底是怎么一回事呢。先看下面的代码,实现死锁:
//死锁的实现
class A
{
public void get(){
System.out.println("A说:我开始启动了,B,给我你的资源");
}
public void say(){
System.out.println("A获得资源");
}
}
class B
{
public void get(){
System.out.println("B说:我开始启动了,A,给我你的资源");
}
public void say(){
System.out.println("B获得资源");
}
}
class MyThread implements Runnable
{
public static A a = new A();
public static B b = new B();
public boolean flag = false;
public void run(){
if(flag){
synchronized(a){
a.get();
try{
Thread.sleep(500);
}catch(InterruptedException e){}
synchronized(b){ //此同步代码块在另一同步代码块里
a.say();
}
}
}else{
synchronized(b){
b.get();
try{
Thread.sleep(500);
}catch(InterruptedException e){}
synchronized(a){ //此同步代码块在另一同步代码块里
b.say();
}
}
}
}
}
public class Demo24
{
public static void main(String args[]){
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
mt1.flag=true;
mt2.flag=false;
Thread th1 = new Thread(mt1);
Thread th2 = new Thread(mt2);
th1.start();
th2.start();
}
}
以上代码由于synchronized的同步造成了死锁,死锁是两个或多个线程同时等待对方的完成,而程序无法继续执行。在解释代码前,首先要明白synchronized到底是怎么一回事。synchronized定义同步,那么同步的什么,什么和什么同步了?
首先,我们得知道,什么是锁。在java中,每一个对象都有一个内部锁,如果以方法或代码块用synchronized进行声明,那么对象的锁将保护整个方法或代码块,要调用这个方法或者执行这个代码块,必须获得这个对象的锁。而且,任何时候都只能有一个线程对象执行被保护的代码
在以上代码中,
在线程th1启动后,他就获得了a的锁,同时当其休眠完毕,求会申请获得b的锁,而此时,他的a锁没有放弃。
在线程th2启动后,他就获得了b的锁,同时当其休眠完毕,求会申请获得a的锁,而此时,他的b锁没有放弃。
两方都握有自己的锁不放弃,而同时申请另一方的锁,所以,此时就造成了死锁。
同步,同步的就是线程和对象,将线程和对象进行绑定,获取对象的锁。
注意:通过以上代码可以发现,死锁的必要条件是不放弃已有的锁,而同时申请新锁。所以,要想实现死锁,就会有synchronized的嵌套。
这样才能同时操作两个以上的锁,从而造成死锁。
分享到:
相关推荐
### Java多线程-避免同步...综上所述,了解和掌握 Java 多线程中的死锁问题及其解决方案对于开发高质量的并发应用程序至关重要。同时,合理利用 `Lock` 接口提供的功能可以帮助开发者更加灵活地管理线程间的同步问题。
但是,随着JVM的优化,`synchronized`现在具有锁升级的特性,开始时使用偏向锁,当多线程争抢时升级为轻量级锁,再进一步升级为重量级锁,这种优化降低了锁的开销。 4. **监视器锁与对象锁的关系**: 每个Java对象...
2.对于“不可抢占”这个条件,占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它所占有的资源,这样不可抢占这个条件就破坏掉了。 3.对于“循环等待”这个条件,可以靠按序申请资源来预防,...
Java线程是多任务编程的核心概念,特别是在服务器端和分布式应用中,它使得程序能够同时执行多个任务,提高系统的并发性和...在这个“java线程demo”中,你可以找到实用的示例和代码片段,进一步加深对这些概念的理解。
并发编程的核心挑战在于正确地管理共享资源,避免数据竞争和死锁等问题。Java的`synchronized`关键字是用于实现线程同步的关键工具,它可以确保同一时刻只有一个线程能访问特定的代码块或方法,从而确保了线程安全。...
JAVA提供了强大的多线程支持,包括线程的创建、同步机制(如synchronized关键字、wait()和notify()方法)、死锁和活锁问题,以及并发工具类如ExecutorService、Semaphore和CyclicBarrier等。 再者,JAVA集合框架是...
通过阅读这些代码和文档,开发者可以进一步理解并掌握Java多线程编程的精髓,提升自己的编程技能。 总之,Java的多线程和同步机制是构建高效并发应用程序的关键。从这个压缩包中学习,我们可以深入理解Java的并发...
在Java中,synchronized和volatile关键字可以帮助保证某些操作的原子性。synchronized提供互斥访问,保证同一时刻只有一个线程执行特定代码块;volatile则保证对变量的读写操作是原子性的,并且能立即反映到其他线程...
避免死锁的方法包括避免循环等待、设置超时和使用死锁检测算法。 九、线程中断 Thread类提供了interrupt()方法用于中断线程,但是需要注意的是,中断并不是立即停止线程,而是设置一个中断标志,线程需要在适当的...
相反,粒度较细的锁(如实例级别锁)可以让更多线程并发执行,提高性能,但也可能增加锁竞争和死锁的风险。因此,在设计多线程程序时,我们需要根据实际情况权衡锁的粒度,以达到最佳的并发性能和安全性。 总结来说...
4. **多线程**:Java提供了强大的多线程支持,面试中可能涉及线程的创建、同步机制(如synchronized、volatile、Lock接口)、死锁、线程池等概念。理解并发编程的原则和陷阱至关重要。 5. **异常处理**:Java中的...
理解synchronized的工作原理,包括锁的获取和释放、死锁、可重入性等,对于解决并发问题至关重要。 其次,volatile关键字是另一种处理并发问题的手段,主要用于保证内存可见性和禁止指令重排序。当一个变量声明为...
在IT领域,多线程编程是一项关键技能,尤其是在性能优化和并发处理方面。多线程允许一个程序同时执行多个不同的任务,从而...你可以进一步研究代码中的线程创建、同步机制和其他相关功能,以增强你的多线程编程能力。
避免死锁的方法包括避免循环等待、设置超时、资源预分配和使用死锁检测算法。 在多线程环境中,线程安全的数据结构和集合显得尤为重要。例如,Java提供了ConcurrentHashMap、ArrayList的线程安全版本Collections....
此外,Java还提供了synchronized关键字、volatile变量、wait()、notify()和notifyAll()等工具来处理线程间的同步和通信,以避免竞态条件和死锁。 在Java多线程教学演示系统中,我们将使用这些概念来设计和实现一个...
理解同步机制(如synchronized关键字、wait()、notify()、notifyAll()方法)防止线程间的竞态条件和死锁。 6. **输入/输出流**:Java的I/O流处理涵盖了文件操作、网络通信和数据转换。InputStream和OutputStream...
在Java编程语言中,线程同步是一个至关重要的概念,它涉及到多线程环境下的资源管理和程序执行顺序。本文将深入探讨“同步线程的应用”这一主题,...通过不断实践和学习,我们可以进一步提升在并发编程领域的专业能力。