From 8b26358aa7c3b4ae1cd306a25a8af3193a75d964 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 2 Dec 2018 21:26:52 +0100 Subject: [PATCH] [jdbc-driver] Synchronize access to the handlers map --- .../src/main/java/acolyte/jdbc/Driver.java | 6 +++-- .../test/scala/acolyte/jdbc/DriverSpec.scala | 24 ++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/jdbc-driver/src/main/java/acolyte/jdbc/Driver.java b/jdbc-driver/src/main/java/acolyte/jdbc/Driver.java index a946efaa..d2729c42 100644 --- a/jdbc-driver/src/main/java/acolyte/jdbc/Driver.java +++ b/jdbc-driver/src/main/java/acolyte/jdbc/Driver.java @@ -1,5 +1,7 @@ package acolyte.jdbc; +import java.util.Collections; +import java.util.Map; import java.util.Properties; import java.util.HashMap; @@ -31,8 +33,8 @@ public final class Driver implements java.sql.Driver { /** * Handler registry */ - public static final HashMap handlers = - new HashMap(); + public static final Map handlers = + Collections.synchronizedMap(new HashMap()); // --- Shared --- diff --git a/jdbc-driver/src/test/scala/acolyte/jdbc/DriverSpec.scala b/jdbc-driver/src/test/scala/acolyte/jdbc/DriverSpec.scala index d2347ec0..1766d135 100644 --- a/jdbc-driver/src/test/scala/acolyte/jdbc/DriverSpec.scala +++ b/jdbc-driver/src/test/scala/acolyte/jdbc/DriverSpec.scala @@ -1,10 +1,12 @@ package acolyte.jdbc -import java.util.ServiceLoader +import java.util.{ ServiceLoader, UUID } +import java.util.concurrent.Executors import java.sql.{ Driver ⇒ JdbcDriver, DriverManager } import scala.reflect.ClassTag +import scala.concurrent.{ Await, ExecutionContext, ExecutionContextExecutorService, Future } import org.specs2.mutable.Specification @@ -139,6 +141,26 @@ object DriverSpec extends Specification with DriverUtils with DriverFixtures { getStatementHandler aka "handler" mustEqual h } + + "handle multi-threaded access" in { + import scala.concurrent.duration._ + + implicit val ec: ExecutionContextExecutorService = + ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(16)) + + val futures = + (1 to 1000).map { _ => + Future { + val handlerId = UUID.randomUUID().toString + acolyte.jdbc.Driver.register(handlerId, new CompositeHandler()) + handlerId + }.map { handlerId => + acolyte.jdbc.Driver.handlers.get(handlerId) mustNotEqual null + } + } + + Await.result(Future.sequence(futures), 5.seconds) + } } }