import java.util.*; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; /** * Date: 14-3-2 */ public class TestDeadlock{ public static void main(String[] args){ Q q = new Q(); Config config = new Config(); config.setQ(q); config.setA(new A(config)); config.setB(new B(config)); config.getA().start(); config.getB().start(); } } class Config{ private A a; private B b; private Q q; public A getA() { return a; } public void setA(A a) { this.a = a; } public B getB() { return b; } public void setB(B b) { this.b = b; } public Q getQ() { return q; } public void setQ(Q q) { this.q = q; } } class B extends Thread{ private final byte[] lock = new byte[0]; private Q q ; private Config config; public B(Config config){ System.out.println("lockB="+lock); this.config = config; this.q = config.getQ(); } public void run(){ try{ int i = 0; while (true){ synchronized (lock){ if(!q.getQ().isEmpty()){ try { System.out.println("b waiting..."); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //dead lock code i++; q.getQ().add("B" + i); System.out.println("thread B put B" + i); config.getA().notifyA(); //wait A lock,held B lock } TimeUnit.SECONDS.sleep(2); } }catch (Exception e){ e.printStackTrace(); } } public void notifyB(){ synchronized (lock){ System.out.println("A notify B..."); if(q.getQ().isEmpty()){ // synchronized (lock){ lock.notifyAll(); // } } } } } class A extends Thread{ private final byte[] lock = new byte[0]; private Q q ; private Config config; public A(Config config){ this.q = config.getQ(); this.config = config; } public void run(){ try{ while (true){ synchronized (lock){ if(q.getQ().isEmpty()){ try { System.out.println("a waiting..."); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //dead lock code System.out.println("thread a get " + q.get()); if(q.getQ().isEmpty()){ config.getB().notifyB(); //wait B lock,held A lock } } TimeUnit.SECONDS.sleep(2); } }catch (Exception e){ e.printStackTrace(); } } public void notifyA(){ synchronized (lock){ System.out.println("B notify A..."); if(!this.q.getQ().isEmpty()){ // synchronized (lock){ lock.notifyAll(); // } } } } } class Q { private final BlockingQueue q = new LinkedBlockingQueue(); public void put(Object obj){ q.add(obj); } public Object get(){ return q.poll(); } public Queue getQ(){ return q; } }
不小心写了一段死锁代码,dump出来才知道。如注释处,跑了一下发现,A等B的锁,B却也在等A的锁,形成死锁。
典型的过度同步(effective java)。在同步块中调用外来逻辑容易导致异常、死锁、数据损坏。
以上把锁之外的逻辑移出synchronized块,或者改写notifyA/notifyB的逻辑即可。
相关推荐
使用银行家算法设计并实现一个小型的死锁避免系统。 前段时间做了一个实现银行家算法的小型系统。纯靠控制台操作,如果需要借鉴,则可以点开;如果是想实现gui界面或是网页的大佬,看到这里就可以了。
这段代码在默认的READ COMMITTED隔离级别下运行,两个进程分别在获取一个排它锁的情况下,申请对方的共享锁从而造成死锁。 可见一个进程可以正常更新并显示结果,而另一个进程已经被回滚: (1 row(s) affected)Msg ...
银行家算法是一种重要的死锁避免算法,它通过动态地分配系统资源,确保系统能够安全地运行,避免进程之间相互等待资源而导致的死锁情况。在实际的操作系统中,银行家算法被广泛应用于资源管理和进程调度中。 以下是...
在程序中使用了lock或者ReaderWriterLock,锁资源发生了争用 下面是一小段代码: 代码如下: //_rwLock的类型是ReaderWriterLock _rwLock.AcquireWriterLock(100); DoSomething(); _rwLock.ReleaseWriterLock(); 这...
首先要明白为什么上面这段话能够锁定代码,其中的奥妙就是X这个对象,事实上X是任意一种引用类型,它在这儿起的作用就是任何线程执行到lock(X)时候,X需要独享才能运行下面的代码,若假定现在有3个线程A,B,C都执行到...
经过一段时间的接触TI的开发板,发现TI芯片确实算是比较容易锁死的。我边上有人锁死过,网上也有一大票人锁死过,很幸运的是,今天我也荣幸的锁了一回,我是在调SDRAM时,因为直接load网上下载的代码,导致了芯片锁...
Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...
│ 高并发编程第一阶段20讲、同步代码块以及同步方法之间的区别和关系.mp4 │ 高并发编程第一阶段21讲、通过实验分析This锁的存在.mp4 │ 高并发编程第一阶段22讲、通过实验分析Class锁的存在.mp4 │ 高并发编程...
│ 高并发编程第一阶段20讲、同步代码块以及同步方法之间的区别和关系.mp4 │ 高并发编程第一阶段21讲、通过实验分析This锁的存在.mp4 │ 高并发编程第一阶段22讲、通过实验分析Class锁的存在.mp4 │ 高并发编程...
Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...
答:不会发生死锁,(但有一点int是按值传递的,所以每次改变的都只是一个副本,因此不会出现死锁。但如果把int换做一个object,那么死锁会发生) 30.简要谈一下您对微软.NET 构架下remoting和webservice两项技术的...
无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。 每个对象只有一个锁(lock)与之相关联。 实现同步是要很...
无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。 每个对象只有一个锁(lock)与之相关联。 实现同步是要很...
13.2.1 一段令人困惑的字符串程序 248 13.2.2 “一次投入,终身回报”的String内存机制 249 13.2.3 String对象特殊机制付出的代价 252 13.3 StringBuffer类 253 13.3.1 弥补String不足的StringBuffer类 ...
下面是一系列蓝屏中可能出现的代码. 0 0x00000000 作业完成。 1 0x00000001 不正确的函数。 2 0x00000002 系统找不到指定的档案。 3 0x00000003 系统找不到指定的路径。 4 0x00000004 系统无法开启档案。 5 0x...
对共享资源的操作代码段称为临界区。 影响 : 对共享资源的无序操作可能会带来数据的混乱,或者操作错误。此时往往需要同步互斥机制协调操作顺序。 3. 同步互斥机制 同步 : 同步是一种协作关系,为完成操作,多...
windows蓝屏错误代码 1 0×00000001 不正确的函数。 2 0×00000002 系统找不到指定的档案。 3 0×00000003 系统找不到指定的路径。 4 0×00000004 系统无法开启档案。 5 0×00000005 拒绝存取。 6 0×00000006 无效...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...