package test;import java.util.LinkedList;public class Test_2_A2 { public static void main(String[] args) {
  SubTreadOne one = new SubTreadOne();
  SubTreadTwo two = new SubTreadTwo(one);
  two.start();
  try {   Thread.sleep(1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  one.start(); }}class SubTreadOne extends Thread { public SubTreadOne() {
 } public void run() {
  try {
   System.out.println("sleep");
   Thread.sleep(3000);
   synchronized (this) {
    this.notifyAll();
   }
  } catch (InterruptedException e) {
   e.printStackTrace();
  } }}class SubTreadTwo extends Thread { SubTreadOne one; public SubTreadTwo(SubTreadOne one) {
  this.one = one;
 } public SubTreadTwo() { } public void run() {
  try {
   synchronized (one) {
    System.out.println("wait");
    one.wait();
    System.out.println("wake up");
   }
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }}
请问这题我有点疑惑,打印结果是这样的
wait
sleep
wake up
还有请问这题synchronized (one)这句是什么意思呢?以前我看过的同步都没有后面括号里有对象的呢?还有照理说这题应该打印出来的话只有wait,下面的就不会在执行了,因为two 引用了one所以one的对象就永远处于等候对象,这点我想不同,为什么没有调用notify那one为什么会执行了?疑惑 

解决方案 »

  1.   

    首先synchronized (one)是临界区的意思,在一个方法内部只有一部分代码需要同步的时候可以这样写,锁对象是one,即JVM在One上面加监视器
    平时你所见的同步都没有后面括号里有对象的这种情况,其实非静态方法都是加上this而静态方法是加的那个类的Class对象
    理解了这个,程序的执行结果就确定了
    首先two线程执行
    synchronized (one) {
        System.out.println("wait");
        one.wait();
        System.out.println("wake up");
      } 
    在one上加监视器,打印wait,然后在One上调用wait(),释放One上的锁,同时One监视器上的线程wait
    然后主线程sleep1秒后执行one的run方法
    System.out.println("sleep");
      Thread.sleep(3000);
      synchronized (this) {
        this.notifyAll();
      } 
    打印sleep
    由于one上面的锁已经释放,故执行 this.notifyAll();唤醒one监视器上wait的所有线程
    然后one线程执行完释放锁,two线程继续执行,打印wake up
      

  2.   

    还是不明白,既然one已经被wait()等待notify叫醒了,为什么主线程执行完sleep就回执行one的run方法然后在叫醒wait方法,我想请问下
    public void run() { 
      try { 
      synchronized (one) { 
        System.out.println("wait"); 
        one.wait(); 
        System.out.println("wake up"); 
      } 
    这里面的one与下面的one有相同吗?理解不怎么了????
    public static void main(String[] args) { 
      SubTreadOne one = new SubTreadOne(); 
      SubTreadTwo two = new SubTreadTwo(one); 
      two.start(); 
      try {   Thread.sleep(1000); 
      } catch (InterruptedException e) { 
      e.printStackTrace(); 
      } 
      one.start(); } 
      

  3.   

    SubTreadTwo two = new SubTreadTwo(one); 你不是把one传给two了么?
    two里的one和你生成的one
    当然是一个玩意嘛
      

  4.   

    那他不是在two的run方法里已经调用了wait()了呀怎么还能运行run方法呢
      

  5.   

    wait的是one监视器上的当前线程,
    要执行wait,必须该线程获得one上的锁,然后才能执行wait()方法,然后wait得是该线程
      

  6.   

    1.main线程sleep 1秒2.two 线程给SubTreadOne one加锁;打印出“wait",释放了one上面的锁,并等待其它线程执行one.nodifyAll()方法,使two线程继续排队,竞争one的锁。
    注意:此时加锁的对象只是 SubTreadOne one的引用,并没有SubTreadTwo two 加锁 3.回到main线程 执行 one.start(); 4.main线程 结束,执行one 线程中的run方法,打印出“sleep”(注意:此时的SubTreadOne one对象的锁已经由第2步释放了,所以能够调用),然后给SubTreadOne one 加锁,调用this.modifyAll()方法,唤醒其它在此对象上的等待线程(此处是 two 线程),this的所指向的对象即为one对象
      

  7.   

    5.one线程结束,two 线程又获得 one对象的锁 并由原来的位置继续执行 打印出“wake up”