解决方案 »

  1.   

    主线程中当i=10时,synchronized(b)给b加了锁,但是进入try块后,b.wait()这句代码不是又将b上的锁给释放了吗?
      

  2.   

    首先,如楼上所说,b.wait()这句代码不是又将b上的锁给释放了
    其次,即便没有释放锁,你线程b为什么会被阻塞呢??你在线程b中 又没有使用锁。
      

  3.   

    给b加锁的意思是,对象b只能有一个线程去访问
    搞不明白对象b,调用start()是什么意思,应该先new一个Thread吧,这样:new Thread(b).start();
    当i<10的时候,是线程b在访问b对象,当i=10,给b加锁,这时还是只有线程b在访问,b.wait()会被阻塞阻塞的是主进程b.wait() 之后的内容不会被执行,主进程就死在这儿了。。
    可以在b.wait()前后加上两条输出语句验证
      

  4.   

    1、主类里 b.start(); 之后,你没有sleep,结果下面的循环走完了,你的ThreadB才开始打印;
    2、如果想要阻塞,必须有多个线程去访问锁对象b,可以在ThreadB中的循环中增加synchronized (this) 
      

  5.   

    public class Deadlock{
       public static void main(String[]args){
        lock t1 = new lock(0);
        lock t2 = new lock(1);
        Thread tA = new Thread(t1);
        Thread tB = new Thread(t2);
          tA.start();
          tB.start();
        }
    }class lock implements Runnable{
    static Object o1 = new Object(),o2 = new Object();
    private int flag;
       lock(int flag){
        this.flag = flag;
        }
       public void run(){
        System.out.println("flag is "+flag);
           if(flag==0){
              synchronized(o1){
               try{
               Thread.sleep(1000);
               }catch(Exception e){
               e.printStackTrace();
               }            synchronized(o2){
               System.out.println("1");
               }
               }        
           
            }
            if(flag==1){
            synchronized(o2){
            try{
            Thread.sleep(1000);
            }catch(Exception e){
               e.printStackTrace();
               }
                synchronized(o1){
               System.out.println("0");
               }
            }       
            }
       
        }
    }

    这个是锁死了,双方都拿不到对方的锁
      

  6.   

    synchronized(b)表示主线程拿到b这个锁对象,具体和b没有半毛钱关系,建议楼主再看看相关的知识。
      

  7.   

    obj.wait()执行时 不是obj线程会暂时停止执行,会进入obj的wait set中,并释放锁进入阻塞状态吗
      

  8.   

    我想问下,这个里面进入wait后,有操作把这个线程唤醒吗?
      

  9.   

    我想问下,这个里面进入wait后,有操作把这个线程唤醒吗?
    不是notify吗?
    但是也不能马上进入运行状态,只能让它再次进入可运行,要等CPU分配时间片给它。
      

  10.   

    线程b是不会阻塞的。 
    主线程会阻塞, 因为你的wait方法是在主线程上面调用的。 
    你可以在主线程的循环中把i打印出来。 就能看到效果了。
      

  11.   

    我也看出是ThreadB执行完了,但是执行完了那么该对象上的锁咋办呢???一下
      

  12.   

    我来分析下楼主代码:
    1、调用b.start(),jvm创建一个线程需要一定的时间,b线程还没有启动时,主线程便执行for循环了;
    2、主线程for循环到i=10时,b拿到锁,调用b.wait()后,主线程阻塞,此时开始执行b线程,b线程执行完了便释放锁;
    3、b执行完并释放锁后,主线程继续向下执行;
    4、主线程会执行完毕,不会死锁;
    public class ThreadDemo {
    public static void main(String[] args)throws Exception {
    ThreadB b = new ThreadB();
    b.start();
    for(int i =0;i<30;i++){
                            Thread.sleep(1000);
    if(i==10){
    synchronized(b){
    try{
        b.wait();
    }catch(Exception e){
    e.printStackTrace();
    }
    }
    }
    }
    }
    }
    class ThreadB extends Thread{
    int total;
    @Override
    public void run() {
    for(int i =0;i<30;i++){
    try{
    Thread.sleep(100);
    }catch(Exception e){
    e.printStackTrace();
    }
    total+=i;
    System.out.println("i= "+i);
    }
    }
    }
    若在主线程的for里面加上Thread.sleep(1000),可以保证b线程执行完之前,主线程for中的i还没到10,当主线程for中的i=10时,b线程早已执行完了,此时,b获得锁,调用b.wait(),b释放锁,此时主线程阻塞
      

  13.   


    我想问下,这个里面进入wait后,有操作把这个线程唤醒吗?
      

  14.   

    public class ThreadDemo {
        public static void main(String[] args)throws Exception {
            ThreadB b = new ThreadB();
            b.setDaemon(true);
            b.start();
            for(int i =0;i<30;i++){
                if(i==10){
                    synchronized(b){
                        try{
                            b.wait();
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    class ThreadB extends Thread{
        int total;
        @Override
        public void run() {
            for(int i =0;i<3000000L;i++){
                try{
                    Thread.sleep(100);
                }catch(Exception e){
                    e.printStackTrace();
                }
                total+=i;
                System.out.println("i= "+i);
            }
        }
    }
    程序会一直执行3000000次,主线程也不会退出.