2017-04-07 112 views
2

我想以序列化方式運行一些任務。對此的典型解決方案是創建一個Java:另一個多線程執行程序中的單線程子執行程序

Executor executor = Executors.newSingleThreadedExecutor(); 

並運行此任務上的任務。

但是,我已經有了一個多線程的線程池。

有沒有一種簡單的方法來派生一個行爲像單線程的子執行器(如:一次只運行一個任務),但是使用另一個(可能是非單線程)執行器作爲「後端」而不是創建一個全新的操作系統線程?

有幾個用例爲什麼我們會想這樣做:

  • 的應用程序可能已經有了例如線程池後臺任務, 設置優先級等,我們希望重用。
  • 類似地,我們可能會傳遞一個執行程序,它不只是一個普通的線程池(例如推遲執行購買,測量執行時間等)
    • 其中在MoreExecutors.directExecutor)使(爲一個子集測試(以便例如期貨立即解決)。

編輯:加入上面的例子

+2

你可以把你想要在單線程中運行的任務代碼?我認爲在單線程中運行任務將由任務本身決定。如果您不想在另一個線程的任務內執行任何操作,它只會在同一個線程中運行。 –

+0

我同意Vijendra - 你的問題很有趣,但爲了給予更多有用的反饋,一些代碼可能會幫助我們。 – GhostCat

回答

2

這樣一個零線程執行程序被稱爲SerialExecutor,在java文檔中描述爲java.util.concurrent.Executor。但是它有一點缺點:對於每個提交的Runnable,它都會創建一個包裝對象。 My own implementation不會創建其他對象。

+0

很酷,謝謝!雖然他們會在java _docs_中放置一個有用的類,而不是實際的代碼,但有些令人驚訝,我不知道它從那裏複製了多少次。 – Latanius

0

我的建議:不要去那裏。

從實際的角度來看,這並沒有多大意義:你願意爲一個問題引入一個更復雜的解決方案......這不是一個真正的問題。

你會看到:當那個「其他」多線程服務空閒時......爲什麼要把它放在第一位呢?如果你想保存OS線程;爲什麼你使用那種似乎厭倦缺乏工作的多線程服務?

但是,如果它不是閒置 - 您認爲您可以從該「單線程」服務「分階段」完成任務嗎?以一致的方式?

是的,線程並不是很便宜;但是當你確實在保存單個線程爲你解決問題的時候......回去一個段落並再次問自己:那個閒置的多線程服務呢?

所以,也許有一種技術方法來實現你的想法;不過實話說;我的答案是 - 堅持你已經有了:

Executor executor = Executors.newSingleThreadedExecutor(); 

並增加對其他答案/評論:是角色模型可以幫助這裏;但混淆概念很少是一個好主意。如果Actor方法很好地適合你的整體模型(也許有很好的方法來改變你的代碼的更多部分來利用它) - 很好。但是,如果沒有;要小心增加額外的概念複雜性只是爲了解決一個問題......正如所說的那樣;首先可能不是真正的問題。

+0

starter需要的主題實際上是一個Actor,它接受類型爲Runnable的消息並通過調用message.run()來處理它們。 Actor的概念並不複雜,足夠直觀,並且在過去的40年裏得到了成功的開發。詳情請參閱https://github.com/rfqu/CodeSamples/tree/master/src/simpleactor –

+0

我喜歡你的簡短回答;從而提高了;但經過一段時間的思考後,我決定保留我的答案。一切都取決於OP真正具有的「多大的問題」。我們不做事,因爲我們可以,但是因爲它們有意義並且改進了一些值得改進的東西。而且這個解決方案今天在兩個池中運行;通過重新使用一個泳池來取得什麼成果? (可能很多,但這實際上取決於他在做什麼,以及發生的規模)。 – GhostCat

+0

感謝您的回答!我確實同意,對於大多數情況來說,這可能是個好主意,操作系統線程畢竟不是那麼昂貴。但是,如果可能有用,可能會出現更多奇怪的情況;看到我上面添加的例子。 – Latanius