2010-05-26 58 views
2

我已经创建了简单的程序来测试Java中的线程。我希望它可以无限地打印我的数字,如123123123123123.不知道为什么,但是目前它在一个循环完成后仅停止213。有人知道为什么Java中的线程

public class Main { 
    int number; 

    public Main(int number){ 
    } 

    public static void main(String[] args) { 
     new Infinite(2).start(); 
     new Infinite(1).start(); 
     new Infinite(3).start(); 
    } 
} 

class Infinite extends Thread { 
    static int which=1; 
    static int order=1; 
    int id; 
    int number; 
    Object console = new Object(); 

    public Infinite(int number){ 
     id = which; 
     which++; 
     this.number = number; 
    } 

    @Override 
    public void run(){ 
     while(1==1){ 
      synchronized(console){ 
       if(order == id){ 
        System.out.print(number); 
        order++; 
        if(order >= which){ 
         order = 1; 
        } 
        try{ 
         console.notifyAll(); 
         console.wait(); 
        } 
        catch(Exception e) 
        {}      
       } 
       else { 
        try{ 
         console.notifyAll(); 
         console.wait(); 
        } 
        catch(Exception e) 
        {}      
       } 
      } 
      try{Thread.sleep(0);} catch(Exception e) {} 
     } 
    } 
} 

回答

9

您的每一个Infinite实例是同步的,然后就等着上自己的console对象的通知。一旦线程到达console.wait(),它不会继续。

您似乎希望它们都在同一个对象上进行同步 - 因此您需要例如使console为静态。

+0

这就是我的想法。事实上,当我复制相同的代码并删除了.wait()和.notifyAll()时,我停止了程序运行时,我的控制台上印着一串数字。 – npinti 2010-05-26 17:51:13

1

记住System.out.print(..)不会自动刷新输出。

另外,请看java.util.concurrent.Semaphore。你可能能够做你正在尝试的东西(按预定义的顺序执行线程),而无需同步和调用等待。

2

每个线程正在同步一个不同的对象。当控制转到console.wait()时,正在执行的线程将等待另一个线程对控制对象调用notify()/ notifyAll()。没有其他线程正在这样做,因为每个线程都有自己的控制对象副本。因此,所有线程在打印一次后都会无限期地等待。为了解决这个问题,保持所有线程都可以等待的通用对象。