2010-04-20 14 views
2

我有一個特定的Java客戶端庫的問題。這裏的情況是:庫缺陷證明與開發者側應用程序錯誤

我已使用該庫的程序。該程序是一個名爲'WorkerThread'的類,它擴展了Thread。爲了啓動它,我創建了一個Main類,它只包含一個啓動線程的main()函數,沒有別的。工作人員使用庫來執行與服務器的通信並獲得結果。 當我想同時運行2個WorkerThreads時出現問題。我首先做的是這樣做的主要類:

public class Main 
{ 
    public static void main(String args[]) 
    { 
     new WorkerThread().start(); // 1st thread. 
     new WorkerThread().start(); // 2nd thread. 
    } 
} 

當我運行此,這兩個線程產生不合理的結果更有甚者,一些成果應該由第一個線程收到上述第二接收,而不是。

如果不是上述情況,我就跑每一個線程的2個獨立的進程,然後一切工作正常。

另外:

1.有內部的WorkerThread不使用靜態類或方法可能導致的問題。我的應用程序只包含工作線程類,並且不包含靜態字段或方法
2.該庫應該可用於多線程環境。在我的線程中,我只是創建一個庫的類的新實例,然後調用它的方法。而已。

我的問題是這樣的: 不知道我的實現的任何細節,上面的情況和事實足以證明在圖書館有一個錯誤,而不是在我的程序?假設圖書館可能會使用靜態對象或庫創建的線程之間共享的對象(這是由我的2個線程間接共享的並導致此問題)是否安全?如果沒有,那麼錯誤來源於工人階級代碼的假設情況是什麼?

編輯:我沒有說的庫,因爲我想知道,如果以上事實可以獨立於庫的產生回答我的問題,但無論如何,該庫是兔子MQ Java客戶端。每個線程創建1個連接和2個通道,並使用一個發佈數據和一個接收結果。

編輯2:新的事實:問題似乎取決於在哪我送東西給隊列的速度。發送速度較慢會降低錯誤結果的數量。

+0

結果如何收到?在控制檯上? – Bozho 2010-04-20 17:44:34

+2

你應該首先用絕對最小的邏輯來製作一個非常簡單的程序版本,但函數調用庫。圖書館是否聲稱完全是線程安全的?可能有API調用不是。另外,讓我們知道如果庫是lib,將會提供什麼幫助,因爲我們可能有同樣的問題。 – 2010-04-20 17:45:00

+0

是和否:在它們顯示在控制檯中之前,工作線程檢查它是否得到預期的結果,如果它沒有得到預期的結果,它會使用System.err來顯示它 – Paralife 2010-04-20 17:47:11

回答

1

我會假設問題出現在圖書館中。但是,我會更進一步,檢查圖書館資源(或使用decompiler)並查看(也許使用調試器)實際發生的情況。

這樣,你都將證明這個問題是不是在你的代碼&可以提交一個有價值的錯誤報告。

+0

這就是我現在正在做的。但我急於提供結果,並想知道我是否應該只使用我的代碼或使用其他庫。之後,因爲我喜歡特定系統(它是rabbit mq,而我所談論的庫就是它的java客戶端),所以我會嘗試查看源代碼。 – Paralife 2010-04-20 17:55:36

0

如果不知道圖書館是做什麼的,很難猜測。即使庫設計用於多線程環境,它仍然可能需要來自調用者代碼(即您)的一些額外操作才能正常工作。想象一下,庫是一個數據庫驅動程序,並且你的線程對同一個數據庫做了一些事情。如果線程中的DB請求沒有正確地分組到具有適當隔離級別的事務中,那麼結果可能會很糟糕。

但是,如果圖書館不應當與某個共享資源的工作,賠率有什麼毛病庫都很高。在這種情況下,創建一個證明不良行爲的最小測試應用程序並將其作爲錯誤報告提交給庫的作者可能是個好主意。

+0

在您的示例中,您隱式假定我共享同一個連接我的線程。但在我的情況下,它就像我第一次啓動線程,並在它內部創建連接到數據庫 – Paralife 2010-04-20 18:38:57

0

從你的描述中,我會說問題是庫打開到服務器的單一連接,它沒有做任何事情來多個工作線程的訪問。每個進程模型的一個線程工作的原因是服務器認爲分離連接並且永遠不會想到混合它們。

我不知道你是否可以稱這是一個錯誤。由於我們不瞭解更多關於圖書館的問題。可能會出現這樣的情況,您需要負責傳入一個額外的ID,以便在每次請求時返回以找出正確的目標。或者可能是圖書館希望你正確地序列化你的交互。在這種情況下,你需要選擇一個合適的地方來同步你的訪問權限。

+0

這絕對不是原因,因爲在每個線程中我明確打開一個單獨的連接。此外,該庫是rabbitmq java客戶端。我編輯了這個帖子來提及它。 – Paralife 2010-04-20 18:00:05

0

您的庫可能不是無條件線程安全的,但是有條件地線程安全。如果沒有圖書館所有者/供應商提供的必要文檔,我想這很難理解。 您的圖書館可以有條件線程安全的,其根據約書亞·布洛克 -

像無條件線程安全的, 除了一些方法需要 安全 同時使用外部同步。例子包括由 Collections.synchronized包裝返回 集合, 其迭代器需要外部 同步

0

不知道我 實現的任何細節,是上述情況 和事實足以證明,有 是庫中的一個錯誤,而不是我的 程序中的錯誤?

如果否,那麼在什麼假設 情況可以在錯誤中 工人階級代碼產生的?

一個假設的情況是,當你的兩個線程發佈,並從相同的隊列/主題接收,你有消息排序的預期,無論是你的程序(例如,通過線程間的協調),也沒有API /庫保證。

+0

我沒有消息訂購期望,並且線程間同步不是問題,因爲: 1.線程之間不共享任何內容。 2.當我從不同的jvm運行線程時,一切正常。這至少證明了線程不需要訪問私有空間外的任何東西,也不需要與其他線程同步任何東西。線程阿拉孤立。從字面上看,我通過static void main(){thread.start();}啓動線程。線程需要的所有東西都會在它自己的空間中創建它。有人甚至可能會爭辯說我不需要線程。 – Paralife 2010-04-20 18:20:08

+0

另外它證明了任何消息訂購期望的原因(我不會)並沒有得到滿足與發送到同一隊列無關。在兩個獨立的jvm版本中,進程仍然通過各自的私有連接發送到相同的隊列。 – Paralife 2010-04-20 18:26:23

+0

JVM需要時間來啓動,並且在同一個JVM中運行的兩個線程之間出現的時序敏感可能不會在兩個獨立JVM中執行的線程之間出現。除非,直到我們看到工人代碼,並且指定具體的問題是什麼,否則我看不到確鑿的答案。 – 2010-04-20 18:38:45

相關問題