- Java code
class Dead implements Runnable{ private Object o1 = new Object(), o2 = new Object(); int flag = 0; public void run() { if(flag == 0) { synchronized(o1) { try{ Thread.sleep(500); System.out.println("打印输出!~~~"); }catch (Exception e) {} } synchronized(o2) { System.out.println("没有出现了死锁"); } } if(flag == 1) { synchronized(o2) { try { Thread.sleep(500); System.out.println("打印输出!~~~"); } catch (Exception e) { } } synchronized(o1) { System.out.println("没有出现了死锁"); } } }}class Test{ public static void main(String [] args) { Dead d1 = new Dead(); Dead d2 = new Dead(); d1.flag = 0; d2.flag = 1; Thread t1 = new Thread(d1); Thread t2 = new Thread(d2); t1.start(); t2.start(); }}
补充些问题再: servlet的多线程大概是怎样实现的?。。 我所知道的是session处于线程的范围内,一个session就相当于一个线程了,
RMI 远程方法调用, 是通过委托或代理 来完成, 我总觉得真实的对象已经通过远程复制到了本地址上; 可是我怎么听人说; 只是传去一个参数,然后对象在远程处理, 将结果返回到本地! , 这里听这有点不太理解; 请高人指点!~~
------解决方案--------------------
首先你的锁对象都是不同的,另外没有形成互锁条件,采用如下代码就好了:
- Java code
class Dead implements Runnable{ private static Object o1 = new Object(), o2 = new Object(); int flag = 0; public void run() { if(flag == 0) { synchronized(o1) { try{ Thread.sleep(500); System.out.println("打印输出!~~~"); synchronized(o2) { System.out.println("没有出现了死锁"); } }catch (Exception e) {} } } if(flag == 1) { synchronized(o2) { try { Thread.sleep(500); System.out.println("打印输出!~~~"); synchronized(o1) { System.out.println("没有出现了死锁"); } } catch (Exception e) { } } } }}public class Test{ public static void main(String [] args) { Dead d1 = new Dead(); Dead d2 = new Dead(); d1.flag = 0; d2.flag = 1; Thread t1 = new Thread(d1); Thread t2 = new Thread(d2); t1.start(); t2.start(); }}
------解决方案--------------------
还是常犯的错误啊~~
线程死锁的概念是理解了
但是没有注意到,你究竟创造了多少个 "可用资源"
你现在有2个Runnable对象,也就是有两对o1,o2(d1.o1,d1.o2,d2.o1,d2.o2)
你的t1抱的是d1.o1,t2抱的是d2.o2
自然,t1还可以得到d1.o2,t2也可以得到d2.o1
-----------------
对于这样的错误,基本上是被runnable给搞糊涂了
建议把你的竞争逻辑提取出来作为一个新的对象
这样程序逻辑也清晰
- Java code
class ResourcesDepot(){ private Object o1 = new Object(), o2 = new Object(); public Object geto1(String threadFlag){ synchronized(o1) { try{ Thread.sleep(500); System.out.println(threadFlag+"geted o1,waiting o2...."); }catch (Exception e) {} } synchronized(o2) { System.out.println(threadFlag+"geted o2......."); } } public Object geto2(String threadFlag){ synchronized(o2) { try { Thread.sleep(500); System.out.println(threadFlag+"geted o2,waiting o1...."); } catch (Exception e) { } } synchronized(o1) { System.out.println(threadFlag+"geted o1......."); } } }}