2010-10-17 112 views
1
public class ThreadTest 
{ 
public static Integer i = new Integer(0); 

public static void main(String[] args) throws InterruptedException 
{ 
    ThreadTest threadTest = new ThreadTest(); 
    Runnable odd = threadTest.new Numbers(1, "thread1"); 
    Runnable even = threadTest.new Numbers(0, "thread2"); 
    ((Thread) odd).start(); 
    ((Thread) even).start(); 
} 

class Numbers extends Thread 
{ 
    int reminder; 
    String threadName; 

    Numbers(int reminder, String threadName) 
    { 
    this.reminder = reminder; 
    this.threadName = threadName; 
    } 

    @Override 
    public void run() 
    { 
    while (i < 20) 
    { 
    synchronized (i) 
    { 
    if (i % 2 == reminder) 
    { 
     System.out.println(threadName + " : " + i); 
     i++; 
     i.notify(); 
    } 
    else 
    { 
     try 
     { 
     i.wait(); 
     } 
     catch (InterruptedException e) 
     { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
    } 
    } 
    } 
    } 
} 
} 

回答

-1

您不能将wait()和notify()放在同一个同步块中,因为这只会导致死锁。确保只有等待和通知功能都包裹着这样一个synchronized块:

synchronized (i) { 
    i.wait(); // or i.notify(); 
} 
0

由于文档状态异常时

当前线程不是这个对象监视器

的所有者抛出

报告还指出,

这种方法抄只能由作为此对象监视器所有者的线程调用。

而这个条件可以通过

  • 通过执行对象的同步实例方法获得。
  • 通过执行同步对象的同步语句的主体。
  • 对于Class类型的对象,通过执行该类的同步静态方法。

您可以尝试从使用i的类中调用wait方法。这可以通过扩展该类并为notifywait编写两种新方法来完成。

3

您不能在i上同步,因为它在执行程序期间发生更改。

由于在Java中Integer是不可改变的,执行i++i将包含到另一个对象,而不是你有​​的对象的引用之后。因此,您不能在这个新对象上调用wait()/notify(),因为这些方法可能只能在您对​​的对象上调用,否则您将获得IllegalMonitorStateException

您需要在执行过程中不会更改的某个其他对象上进行同步。例如,可为此目的创建一个单独的对象:

public class ThreadTest { 
    public static Integer i = new Integer(0); 
    public static Object lock = new Object(); 
    ... 
    class Numbers extends Thread { 
     ... 
     @Override 
     public void run() { 
      ... 
      synchronized (lock) { 
       ... 
       lock.notify(); 
       ... 
       lock.wait(); 
       ... 
      } 
     } 
    } 
} 
+0

+1,打我吧:) – SimonJ 2010-10-17 15:43:05

+0

感谢真的gelped我很多 – Ajay 2010-10-27 17:47:44

1

这条线:

i++; 

相当于:

i = i + 1; 

其中(由于自动装箱)变得像:

i = new Integer(i.intValue() + 1); 

因此,当您拨打i.notify()时,您将在i上同步,而不是新的。

我建议改变i成普通int变量,并创建一个单独的对象进行同步的:

static int i = 0; 
static Object iMonitor = new Object(); 
+0

感谢你的回复..真的帮助了我 – Ajay 2010-10-27 17:46:19

相关问题