日期:2014-05-20  浏览次数:20812 次

为什么没有出现死锁?。。。
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.......");
            }
        }
    }

}