2011-11-21 77 views
1

我有一个应用程序,它的主要方法产生了一百个线程(假设我们模拟一百个帐户)。我正在试验它,我希望它只是在用Control-C进行打印时打印终止。ShutDownHook在多线程应用程序

我看了你可以做到这一点ShutDownHooks,所以我说在我的主要方法如下:

Runtime.getRuntime().addShutdownHook(new Thread() { 
      public void run() { 
          System.out.println("Terminating"); 
         } 
     }); 

然而,当我运行它没有被打印出来。

请问我可以提供一些指导,告诉我哪里出错了(所有线程都在for循环中声明并从调用start方法开始)?

问候, 乔治

编辑:请参阅下面的代码:

银行类:

public class Bank { 
private final double[] accounts; 
    public Bank(int n, double initialBalance) { 
    accounts = new double[n]; 
    for (int i=0; i < accounts.length;i++) { 
     accounts[i] = initialBalance; 
    } 
} 
    public double getTotalBalance() { 
     double sum = 0.0; 
     for (int i=0; i < accounts.length; i++) { 
      sum += accounts[i]; 
     } 
     return sum; 
    } 
    public synchronized void transfer(int fa, int ta, double amt) throws InterruptedException{ 
     System.out.print(Thread.currentThread()); 
     if (accounts[fa] < amt){ 
         wait(); 
        } 
     accounts[ta] -= amt; 
     System.out.println("Transfer of amount: " + amt + " from: " + fa + " Transfer to: " + ta); 
     accounts[fa] += amt; 
     System.out.println("Total Balance: " + getTotalBalance()); 
     notifyAll(); 

} 
public int size() { 
    return accounts.length; 
} 
public double[] getAccounts(){ 
    return accounts; 
} 

} 

BankTest类:

public class BankTest { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
      Bank b = new Bank(100,1000); 
    int i; 
     long timeStart = System.currentTimeMillis(); 
     long j = System.currentTimeMillis(); 





      for (i=0; i < b.size(); i++) { 
     TransferRunnable tr = new TransferRunnable(b, i, 1000,j); 
     Thread t = new Thread(tr); 
     t.start(); 

    } 
      Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
         System.out.println("Terminating"); 
        } 
    }); 


     } 


    } 

TransferRunnable类:

public class TransferRunnable implements Runnable { 
private Bank b; 
private int fromAccount; 
private double maxAmount; 
private final int DELAY = 40; 
private long timeStart; 
public TransferRunnable(Bank b, int from, double max, long timems) { 
    this.b = b; 
    fromAccount = from; 
    maxAmount = max; 
     timeStart = timems; 
} 
@Override 
public void run() { 

     try { 
     while (true) { 
      int ta = (int) (b.size() * Math.random()); 
      double amount = maxAmount * Math.random(); 
        double[] acc = b.getAccounts(); 
        b.transfer(fromAccount,ta,amount); 
      Thread.sleep((int) (DELAY*Math.random())); 
     } 
    } 
     catch (InterruptedException e) { 

     } 

    } 

} 
+0

正如我在答复中回答的那样,你能说出运行时系统的细节吗? –

+0

Windows 7与JDK 1.6.0_10 – user998388

回答

0

当我运行它时会打印出来。您可以将System.out.flush();添加到run()方法的末尾,但这样可以确保立即打印输出。

+2

其实,system.out已经在每个println上刷新。 – jtahlborn

+0

在JRE中它通常会这样做,但是我只是查找了System.out和println的描述,并且它没有明确*需要*自动刷新。然后,这可能是接收“派对”缓冲,然后过早关闭。所以我们需要知道提问者正在运行的系统。 –

+0

我在命令提示符下尝试了Cygwin和Windows。打印线程时是否打印?不知道如何在不创建新线程的情况下发布代码 - 请指教。 – user998388

0

正如其他人所说,这应该只是工作。你在使用什么操作系统?这可能是因为CTRL+C完全杀死了这个进程,而不是让它关闭(例如SIGKILL vs SIGINT)。你可以验证你发送Java过程的信号吗?

最后,作为最后的手段,你可以尝试的Java的以下位:

if (FileDescriptor.out.valid()) { 
    FileDescriptor.out.sync(); 
} 

我怀疑这会不会有任何区别,但!

+0

有什么想法?我在Windows上使用JDK和Netbeans。 – user998388