2011-11-21 121 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