我有以下功能,想知道,如果它产生副作用:
def build[F[_] : Monad : Foldable, A]
(consumer: Consumer[String, String])(cb: Vector[KkConsumerRecord] => F[A])
: KkConsumerThread = {
val thread = delegate.newThread(() => {
pool(consumer)(cb)
})
thread.setDaemon(true)
KkConsumerThread(thread)
}
在函数内部,我创建了一个线程,但还没有启动它。这对我来说意味着,我还没有产生任何副作用。我是对的吗?
答案 0 :(得分:3)
基本上,您似乎 会产生副作用。这样考虑一下 - 如果你反复调用这个函数,你最终会耗尽内存(通过达到OS线程#limit或java堆大小限制)。
答案 1 :(得分:1)
你在这里产生了几个副作用:
从或多或少透明thread.setDaemon(true)
开始,假设您只执行一次(并且在您返回false
之前似乎没有人阅读KkConsumerThread
)
delegate.newThread(
在JVM中注册新线程(假设它创建了一个JVM线程):http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Thread.java#393,因此它可能在JConsole / JVisualVM / jstack中看作是未启动的线程:
g.addUnstarted(); //adding thread to default THread group
... //a lot of other global mutable stuff
所以,你应该小心线程生命周期(如果你经常调用它),特别是如果你做其他一些低级别的东西。
P.S。据我所知,新线程的创建也会立即(在开始之前)分配一个调用堆栈。