1717import java .util .Collections ;
1818import java .util .HashSet ;
1919import java .util .Set ;
20+ import java .util .concurrent .CountDownLatch ;
21+ import java .util .stream .IntStream ;
2022
2123import static org .hamcrest .Matchers .sameInstance ;
2224import static org .mockito .Mockito .any ;
@@ -38,10 +40,30 @@ public void setup() {
3840 when (projectMetadataMock .custom (eq (StreamsMetadata .TYPE ), any ())).thenReturn (streamsMetadataMock );
3941 }
4042
41- public void testGetInstanceReturnsSingleton () {
42- StreamsPermissionsUtils instance1 = StreamsPermissionsUtils .getInstance ();
43- StreamsPermissionsUtils instance2 = StreamsPermissionsUtils .getInstance ();
44- assertThat (instance1 , sameInstance (instance2 ));
43+ public void testGetInstanceIsSingletonUnderMultithreadedAccess () throws Exception {
44+ int threadCount = 20 ;
45+ StreamsPermissionsUtils [] instances = new StreamsPermissionsUtils [threadCount ];
46+ CountDownLatch startLatch = new CountDownLatch (1 );
47+ CountDownLatch doneLatch = new CountDownLatch (threadCount );
48+
49+ IntStream .range (0 , threadCount ).forEach (i -> new Thread (() -> {
50+ try {
51+ startLatch .await ();
52+ instances [i ] = StreamsPermissionsUtils .getInstance ();
53+ } catch (InterruptedException e ) {
54+ Thread .currentThread ().interrupt ();
55+ } finally {
56+ doneLatch .countDown ();
57+ }
58+ }).start ());
59+
60+ startLatch .countDown ();
61+ doneLatch .await ();
62+
63+ StreamsPermissionsUtils first = instances [0 ];
64+ for (int i = 1 ; i < threadCount ; i ++) {
65+ assertThat (instances [i ], sameInstance (first ));
66+ }
4567 }
4668
4769 public void testStreamTypeIsEnabledReturnsTrueWhenLogsEnabled () {
0 commit comments