簡體   English   中英

在ThreadPool的任務隊列中維護類型信息

[英]Mantaining type information on the queue of tasks of a ThreadPool

我通過2本書非常自學並發:
-來自Brian Goetz 的JVM中的並發
-從Aleksandar Prokopec 學習Scala中的並發編程

據我所知,我正在嘗試構建一個具有固定數量線程的裸ThreadPool。
該線程正在對任務隊列進行輪詢。
ThreadPool為我提供了一種在隊列中插入任務的方法,並返回MyFutureTask[T] ,我希望它是對Java中實際FutureTask[T]的仿真,以便以后可以檢索該值。

 def addTask[T](theTask: () => T): MyFutureTask[T] = queue.synchronized {
  val myFutureTask: MyFutureTask[T] = new MyFutureTask[T] {
    override val task: () => T = theTask
  }
  queue.enqueue(myFutureTask)
  queue.notify()
  myFutureTask
 }

如果我不在乎我提交的任務的返回值(即Runnable),則可以為任務隊列使用適當的類型,即MyFutureTask[Unit]
private val queue = mutable.Queue[MyFutureTask[Unit]]()

然而,當任務返回,我以后要檢索值,這將需要的任務隊列不是有一個正確的類型,因為我需要提交給線程池多個任務,每一個不同的返回類型(TASK1: () => String ,task2: () => Int ,task3: () => SomeProperType SomeProperType ...),這將導致:

private val tasks = mutable.Queue[MyFutureTask[_]]()

這讓我感到不安,因為在Scala中,所有未鍵入的內容都被皺眉了。

所以我的問題是:
1-我上面說錯了嗎? 我是否缺少一些導入步驟? 還是這根本不是正確的方法?
2- 不可避免的是,在實際的ThreadPool實現中,任務隊列沒有正確的類型嗎?
3-如果不可避免,是否有任何不利之處? 這甚至是一個問題嗎?

謝謝,

這與JVM中的“類型擦除”有關,該類型被JVM上運行的所有語言所繼承。 簡而言之,泛型由編譯器檢查,然后被擦除,因此,如果要混合類型的集合,則集合的類型參數必須是所有可能類的超類。 是的,當您從集合中檢索數據時,您將剩下超類。

我認為Shapeless的HList可讓您在列表中保留多種類型。

否則,您需要進行投射。 如果需要,我可以使用類似於以下的功能:

def dequeue[T](tasks: mutable.Queue[MyFutureTask[Any]]) = tasks.dequeue().asInstanceOf[MyFutureTask[T]]

我不明白為什么您的隊列根本不需要知道返回類型。 只需使其在Runnables運行即可:

 def addTask[T](theTask: () => T): Future[T] = { 
   val result = Promise[T]()
   val myFutureTask: Runnable = new Runnable {
     override val run() {
        result.complete(Try { theTask() })
     }
   }
   queue.synchronized { 
     queue.enqueue(myFutureTask)
     queue.notify()
   }
   result.future
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM