diff --git a/akka-actor/src/main/scala/akka/dispatch/BalancingDispatcher.scala b/akka-actor/src/main/scala/akka/dispatch/BalancingDispatcher.scala index a6042046ff..d8274d810a 100644 --- a/akka-actor/src/main/scala/akka/dispatch/BalancingDispatcher.scala +++ b/akka-actor/src/main/scala/akka/dispatch/BalancingDispatcher.scala @@ -9,7 +9,8 @@ import akka.actor.{ ActorCell, ActorRef } import java.util.concurrent.{ LinkedBlockingQueue, ConcurrentLinkedQueue, ConcurrentSkipListSet } import annotation.tailrec import java.util.concurrent.atomic.AtomicBoolean -import akka.util.Duration +import akka.util.{ Duration, Helpers } +import java.util.Comparator /** * An executor based event driven dispatcher which will try to redistribute work from busy actors to idle actors. It is assumed @@ -35,10 +36,13 @@ class BalancingDispatcher( _shutdownTimeout: Duration) extends Dispatcher(_prerequisites, _id, throughput, throughputDeadlineTime, mailboxType, _executorServiceFactoryProvider, _shutdownTimeout) { - val buddies = new ConcurrentSkipListSet[ActorCell](akka.util.Helpers.IdentityHashComparator) + val buddies = new ConcurrentSkipListSet[ActorCell]( + Helpers.identityHashComparator(new Comparator[ActorCell] { + def compare(l: ActorCell, r: ActorCell) = l.self.path compareTo r.self.path + })) val messageQueue: MessageQueue = mailboxType match { - case u: UnboundedMailbox ⇒ new QueueBasedMessageQueue with UnboundedMessageQueueSemantics { + case _: UnboundedMailbox ⇒ new QueueBasedMessageQueue with UnboundedMessageQueueSemantics { final val queue = new ConcurrentLinkedQueue[Envelope] } case BoundedMailbox(cap, timeout) ⇒ new QueueBasedMessageQueue with BoundedMessageQueueSemantics { diff --git a/akka-actor/src/main/scala/akka/util/Helpers.scala b/akka-actor/src/main/scala/akka/util/Helpers.scala index 60e6be8b65..25cb279f2e 100644 --- a/akka-actor/src/main/scala/akka/util/Helpers.scala +++ b/akka-actor/src/main/scala/akka/util/Helpers.scala @@ -21,8 +21,18 @@ object Helpers { if (diff > 0) 1 else if (diff < 0) -1 else 0 } - val IdentityHashComparator = new Comparator[AnyRef] { - def compare(a: AnyRef, b: AnyRef): Int = compareIdentityHash(a, b) + /** + * Create a comparator which will efficiently use `System.identityHashCode`, + * unless that happens to be the same for two non-equals objects, in which + * case the supplied “real” comparator is used; the comparator must be + * consistent with equals, otherwise it would not be an enhancement over + * the identityHashCode. + */ + def identityHashComparator[T <: AnyRef](comp: Comparator[T]): Comparator[T] = new Comparator[T] { + def compare(a: T, b: T): Int = compareIdentityHash(a, b) match { + case 0 if a != b ⇒ comp.compare(a, b) + case x ⇒ x + } } final val base64chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+~"