2011-06-21 88 views
4

我的班上有一個非常奇怪的行爲,並且不知道到底發生了什麼。我有一個JSP向AJAX發送一個請求到一個Servlet 2)這個servlet以下面的方式處理這個請求: - 它反映一個類,然後調用一個方法(它作爲JSP中的參數提供),然後將方法的結果輸出回Ajax。Java:同步方法通過反射訪問多次?

所以這裏是原來的問題,然後解決部分問題,我想出了:

到方法的調用正在做幾次,但我不知道爲什麼。 JSP-Ajax只將它稱爲ONCE(多次測試),但是servlet就像「重新加載自己」一樣,並多次調用該方法,從而導致該過程出錯。由於我無法找到servlet發生了什麼,因此我使「反射」方法同步,因此無論請求多少次,一個請求都會完成,然後是另一個請求,依此類推。我在輸出中寫入了一些消息,寫入方法被訪問時以及何時完成作業。

但是......表示已被訪問的消息在結束消息被拋出之前被寫入了好幾次......所以我不明白,也許同步在反射方面效果不好?我錯過了什麼,爲什麼這個方法在完成前多次訪問?根本不明白。你可以幫我嗎?

另外,你是否有任何想法的原始問題(servlet像「重新加載」本身)?在這個問題中,我想可能是發送了一個讓servlet重新加載的頭文件,但是不確定。

編輯:

其實我正在做一個實例。這是我的servlet代碼:

Class clase = Class.forName("com.cargaporinterfase.CargaPorInterfase_"+cd_matriz); Object obj = clase.newInstance(); Method met = clase.getDeclaredMethod(metodo, new Class[]{String.class, String.class});

螞蟻被調用的方法是:

public synchronized String procesar(String url,String nu_spid) throws CargaPorInterfaseException{ //... more processing }

+2

同步應該被強制執行當該方法被反射調用時。也許你可以發佈似乎被多次調用的synchronized方法的代碼。另外,我會在doGet方法開始時以及在調用服務方法之前和之後向servlet本身添加日誌記錄。 –

+1

您每次調用時都使用'createInstance'嗎? 'synchronized'是一個**每個實例**的基礎。 – Andreas

+0

我認爲我的問題是你說Andreas(至少是同步的問題),我在上面的代碼粘貼原始問題。謝謝! –

回答

3

一些假設:

當你說 「它使一個類的反思」我猜這意味着你使用反射來創建一個新的對象。

我猜你所調用的方法是實例方法(不是靜態的)。

因此,如果這些猜測是正確的,使您通過反射同步調用的方法不會阻止調用重疊,因爲您每次都在不同的對象上調用該方法。如果將​​關鍵字添加到方法定義中,它將使用該方法被調用的對象作爲它的鎖。

3

您可能想了解​​做什麼的更多背景。

我做同步的「反射」的方法,所以無論它得到了多少 次請求,一個請求 將完成[...]

​​上的方法是一樣的synchronized(this) {...},其中this是對象上要調用的方法。

很可能您正在使用同一類的多個不同實例(您正在使用反射),在這種情況下​​不會像您想象的那樣工作。 另外,對反射對象的同步完全不同於每個請求的同步(我認爲你必須同步你的Servlet實例,儘管在某些情況下你可能也有多個實例。)