繁体   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