2012-10-30 37 views
2

我正在研究一個基於Java的服務器,其中我將擁有多個線程(每個連接用戶有一個線程+一些額外的線程)。會涉及到一些數據庫連接,所以我一直在想,每當服務器向數據庫發出一個SELECT查詢時,它都會爲此啓動一個新線程,以防止阻塞當前線程。我打算爲此使用連接池,我想我知道該怎麼做。 (我已經看過C3P0)但是,還會有很多更新也涉及到這些語句,但是這些語句直接運行並不重要,在這裏可以延遲。而且由於可能有很多UPDATE聲明,我正在考慮對所有更新聲明擁有單個工作線程。在我看來,這將是能夠重複使用PreparedStatement優勢-objects用於SQL更新語句的Java單工線程

問題: 我怎樣才能從其他線程,告訴UPDATE -worker線程運行一些聲明?我知道多線程以及如何使用同步塊使線程彼此「交談」,但涉及數據庫時,它突然感覺更復雜。我已閱讀準備好的語句和連接不應該在線程之間共享。

的想法,我現在所擁有的關於如何解決這個問題:(不覺得自己是一個很好的解決方案)

使用LinkedBlockingQueue(或另一種隊列)的定製類的信息哪些需要調用的UPDATE語句以及發送它的參數。然後,工作線程會在收到通知時(它將在何時添加到隊列中)讀取此隊列,並在那裏運行適當的方法,該方法將使用相應的準備語句,設置參數並調用它。

編輯:一個糟糕的想法,我認爲我的這種做法是,參數可能是整數,字符串,雙或任何。如何將它們存儲在自定義類中?將它們全部存儲爲字符串感覺不好。

我在這裏的正確軌道或有沒有更好的方法來解決這個問題?

+1

你不需要通知過程 - 只要調用'queue.poll(timeout,timeunit)'就會阻塞,直到有東西被添加到隊列中。 – assylias

+0

@assylias謝謝,這將使它更容易一些。你認爲我是通過使用隊列來做到這一點的? –

+0

哼...忽略我以前的評論:你可以調用'queue.take()',它將阻塞,直到隊列中有東西。你的方法是有道理的 - 你有一個調用'queue.take'的線程來等待查詢放到隊列中,執行它並返回到'queue.take()'。 – assylias

回答

3

不需要顯式的阻塞隊列。您可以有一個工作線程和一個由ExecutorService封裝的工作隊列。至於該值,你可以使用泛型:

class ThreadTask<T> implements Runnable { 
    private T value; 

    public ThreadTask(T value) { 
     this.value = value; 
    } 

    public void run() { 
     // update based on value 
    } 
} 

... 

ExecutorService exec = Executors.newSingleThreadExecutor(); 
exec.submit(new ThreadTask<String>("asdf")); 
exec.submit(new ThreadTask<Integer>(1)); 

單線程執行是一個簡單的工作線程等待隊列中,爲了執行提交的任務。不需要其他明確的管理。

+0

工程就像一個魅力!雖然我做了幾個不同的ThreadTask類,每種類型的UPDATE語句都有一個類。 –