我要求能够计算在类中具有字段通配符原子引用数组的类中调用AtomicReference[V].get
的次数。
为此,首先,我扩展了Java的AtomicReference [V]:
import java.util.concurrent.atomic.{AtomicInteger => AInt, AtomicReference => ARef}
class MyAtomicReference[V] extends ARef[V]{
private val getCounter: AInt = new AInt(0)
def getAndListen(): V = {
getCounter.getAndIncrement()
super.get()
}
def counter(): Int = getCounter.get()
def resetCounter(): Unit = getCounter.set(0)
}
然后我添加了特征AtomicRefCounter
,该特征声明了我希望调用的方法:
import simulacrum.typeclass
@typeclass trait AtomicRefCounter [R[_], T] {
def countGets(container: R[T]): Int
}
最后,我在对象AtomicArrayRefCounter
中定义了默认的DefaultAtomicRefCounters
:
object DefaultAtomicRefCounters {
implicit val arrayOfAtomicsTraverser = new AtomicRefCounter[Array, MyAtomicReference[_]] {
override def countGets(container: Array[MyAtomicReference[_]]): Int = container map(_.counter()) sum
}
}
尽管当我尝试在测试中的相应数组上调用traverseAtomics()时,却看不到它(我正在使用Intellij IDEA):
behavior of "removeO1"
"method" should "remove an element from the pool with time O(1)" in new IntPoolBuilder {
import org.learningconcurrency.traditional_concurrency.helpers.DefaultAtomicRefCounters._
pool.buckets.countGet
}
就我所缺少的内容提供一些建议确实会有所帮助。 simulacrum的使用不是强制性的-如果您认为不知道如何解决此问题,我很想听听。
更新:
这是实现buckets
的方式:
class Pool[T] {
type TimeStampedList = (List[T], Long)
val parallelism: Int = Runtime.getRuntime.availableProcessors * 32
val buckets = new Array[MyAtomicReference[TimeStampedList]](parallelism)
...
答案 0 :(得分:2)
我认为,您可能会错理解隐含的工作方式。
如果我正确阅读了所有内容,则输入您的代码
implicitly[AtomicRefCounter[Array, MyAtomicReference[_]]].countGets(pool.buckets)
应该工作。
如果您想在countGets
上致电Array
,则应使用 EnrichMyLibrary 模式。
object DefaultAtomicRefCounters {
implicit class RichArray(private underlying: Array[MyAtomicReference[_]] extends AnyVal {
def countGets: Int = underlying.map(_.counter()).sum
}
}
答案 1 :(得分:0)
令人失望的是,我无法使其与模拟注释一起使用,因此我遵循了Sascha的建议。我只是稍微修改了他的第二个示例(我无法使其与implictly
一起使用),因此它可以编译并正常工作:
object TraditionalConcurrencyHelpers {
implicit class CountArrayAtomicGetsOps(wrapper: Array[MyAtomicReference[(List[Int], Long)]]) {
def countGets()(implicit atomicRefCounter: AtomicRefCounter[Array, MyAtomicReference[(List[Int], Long)]]): Int = atomicRefCounter.countGets(wrapper)
}
}
有了这个,我可以在数组上调用countGets
了:
behavior of "removeO1"
"method" should "remove an element from the pool with time O(1)" in new IntPoolBuilder {
import TraditionalConcurrencyHelpers._
import org.learningconcurrency.traditional_concurrency.helpers.DefaultAtomicRefCounters._
//call pool.removeO1 (not implemented yet)
pool.buckets.countGets() shouldEqual 1
}