У меня есть требование, чтобы иметь возможность подсчитывать количество раз AtomicReference[V].get
вызывается в классе, который имеет в качестве поля массив подстановочных атомных ссылок.
Для этого, во-первых, я расширил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ИДЕЯ):
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 не является обязательным - если вы чувствуете, что знаете, как решить эту проблему без него, я хотел бы услышать это.
update :
Вот как реализовано buckets
:
class Pool[T] {
type TimeStampedList = (List[T], Long)
val parallelism: Int = Runtime.getRuntime.availableProcessors * 32
val buckets = new Array[MyAtomicReference[TimeStampedList]](parallelism)
...