seman198102 2008-08-07 17:50
浏览 119
已采纳

为什么主线程总是能优先拿到子线程的资源锁呢?

实在不知道如何用一句话描述清楚我的问题,不好意思了
网上看到一篇讲wait/notify的文章,把代码拷下来debug了一下(代码如下所示),发现一个奇怪的问题,主线程总是先拿到b的锁,而b这个线程运行后,始终无法拿到自身的锁,直到主线程内b.wait将b释放掉之后,很不理解,不知道有谁能解答我的疑惑,谢谢!

class ThreadA
  {
   public static void main(String[] args)
   {
   ThreadB b=new ThreadB();
   b.start();
   System.out.println("b is start....");
   synchronized(b)//括号里的b是什么意思,起什么作用?
   {
   try
   {
   System.out.println("Waiting for b to complete...");
   b.wait();//这一句是什么意思,究竟让谁 000-834 wait?
   System.out.println("Completed.Now back to main thread");
   }catch (InterruptedException e){}
   }
   System.out.println("Total is :"+b.total);
   }
  }

  class ThreadB extends Thread
  {
   int total;
   public void run()
   {
   synchronized(this) //
   {
   System.out.println("ThreadB is running..");
   for (int i=0;i<100;i++ )
   {
   total +=i;
   System.out.println("total is "+total);
   }
   notify();
   }
   }
  }

  • 写回答

1条回答 默认 最新

  • iteye_14762 2008-08-07 18:44
    关注

    我把代码拷贝下来运行了一不, 发现运行到[code="java"]b.wait();//这一句是什么意思,究竟让谁 000-834 wait? [/code]这一行就不动了, 一直等待!在我运行过程中, 我发现总是线程b先拿到自身的锁, 所以执行顺序肯定是b线程先执行完, 然后在执行main方法中[code="java"]synchronized (b)// 括号里的b是什么意思,起什么作用?
    {
    try {
    System.out.println("Waiting for b to complete...");
    b.wait();// 这一句是什么意思,究竟让谁 000-834 wait?
    System.out.println("Completed.Now back to main thread");
    } catch (InterruptedException e) {
    }
    }[/code]的这块代码!因为[code="java"]synchronized (b)// 括号里的b是什么意思,起什么作用? [/code]和[code="java"]synchronized (this) // [/code]锁的是同一个对象, 都是b这个实例!而[code="java"]b.wait();//这一句是什么意思,究竟让谁 000-834 wait? [/code]这一名则是要当前线程处于等待状态中, 直到有其它的线程来唤醒它.但由于此时b已经执行完成, 所以不会在调用notify()方法,所以就一直等待了!我改了下你的代码, 让整个流程能正常跑完, 如下:
    [code="java"]class ThreadB extends Thread {
    int total;

    public void run() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }
        synchronized (this) // <2>
        {
            System.out.println("ThreadB is running..");
            for (int i = 0; i < 100; i++) {
                total += i;
                System.out.println("total is " + total);
            }
            notify();
        }
    }
    

    }[/code], 就是加了一个sleep(3000), 这样能让main方法先拿到b的锁, 然后调用wait()方法等待并释放锁, 此时线程b拿到锁, 执行循环并调用notify()方法,唤醒主线程, 直到执行完毕.
    因为notify()和wait()一定要在synchronized中执行, 所以才会出现你代码中中的synchronized.而[code="java"]b.wait();//这一句是什么意思,究竟让谁 000-834 wait? [/code]这你代码中就是为了等待线程b调用notify(); 方法!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)