2013-02-14 101 views
0

我有一個運行大型應用程序的Tomcat服務器。它有類似於此示例兩類:Java方法停止調用

public abstract class ClassA { 
    private static final Logger LOGGER = Logger.getLogger(ClassA.class); 
    // ... 
    public File methodA(ICancellable cancel) { 
    URL request = new URL("an URL"); 
    LOGGER.debug("Calling ClassB.methodB(type)"); 
    File f = classB.methodB(request, "type", cancel); 
    LOGGER.debug("The call to ClassB.methodB(type)" 
       + " returned the File==" + f); 
    // ... 
    } 
} 

public class ClassB { 
    private static final Logger LOGGER = Logger.getLogger(ClassB.class); 
    // ... 
    public static synchronized File methodB(URL url, String type, 
              ICancellable cancel) 
    { 
    final String thisMethodsName = "ClassB.methodB(url: " + url 
          + ", type:" + type + ", cancel: " + cancel + ")"; 
    LOGGER.debug("Entering method: " + thisMethodsName); 
    // ... 
    return f; 
    } 
} 

的應用程序正常工作,並ClassA.methodA()最初調用成功地以ClassB.methodB(),我可以在日誌文件中看到:

[...] 
14/02/2013 12:34:56 DEBUG ClassA:123 - Calling ClassB.methodB(type) 
14/02/2013 12:34:56 DEBUG ClassB:456 - Entering method: ClassB.methodB(url: anURL, type: type, cancel: @1234); 
[...] 
14/02/2013 12:34:56 DEBUG ClassA:125 - The call to ClassB.methodB(type) returned the File=="aFile". 
[...] 

我的問題是後服務器正在工作一段時間,它停止呼叫ClassB.methodB()。應用程序被掛起,它只是將它寫入日誌:

[...] 
14/02/2013 12:34:56 DEBUG ClassA:123 - Calling ClassB.methodB(type) 

這是日誌文件的最後一行。實際上並沒有調用ClassB.methodB()

我懷疑這可能是由於打開的資源,werent關閉,但我試圖找到所有的代碼,做到了這一點,並在修復後,它仍然發生。

什麼可能導致這種情況?我怎樣才能繼續尋找原因?


JVM版本:1.6.0_13 Tomcat的版本:6.0.18

+0

我認爲在極端情況下文件變得非常巨大(即GB +)時,它需要更多時間才能附加到它。 – 2013-02-14 11:55:12

+0

您是否檢查過以前對「ClassB.methodB」的調用實際上已完成? – Qwerky 2013-02-14 11:55:58

+0

下載的文件不大於類似(甚至相同)文件下載的時間。無論如何,我已經等了好幾個小時,應用程序還是什麼也不做。 – 2013-02-14 11:57:27

回答

1

是否有可能有一些涉及代碼,您沒貼一個線程死鎖錯誤?您的ClassB.methodB方法是​​。您可能有一些其他線程持有並且不會釋放ClassB.class上的​​鎖,從而阻止進行日誌記錄的線程獲取該鎖並輸入該方法。

+0

'ClassB.methodB'正在創建第三個線程(讓我們稱之爲* thread3 *),然後等待該線程完成。它從來沒有發生,因爲正在等待從未授予的InputStream。所以* thread1 *在'ClassB.methodB'中等待* thread3 *完成。因爲它從未發生,* thread1 *永遠不會離開synchronized方法,所以* threa2 *從'ClassA.methodA'調用永遠不會進入它。 – 2013-02-27 11:01:02

0
  1. 啓用調試模式並在您的代碼中分配斷點。使用IDE(最好是日食)一步一步來。
  2. Eclipse有findbugs或PMD等插件來掃描代碼並找出可能的錯誤。
  3. 手動通過每個條件,方法調用,循環查看缺陷。

如果你已經編寫完整的應用程序,那麼你會知道在哪裏看。如果不是,那麼檢查所有內容仍然是件好事

+0

只有在服務器中運行時,錯誤纔會在我的開發機器中發生。有了這個特定的開發環境,我無法在開發站調試這個問題,因爲他們無法訪問互聯網,下載的文件必須來自互聯網服務器。 – 2013-02-14 12:26:39