2
* Copyright 2013 Goldman Sachs.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
package com.gs.collections.impl
19
import java.util.concurrent.TimeUnit
20
import org.junit.Assert
22
trait ThreadSafetyTestTrait
24
def createReadLockHolderThread(gate: Gate): Thread
26
def createWriteLockHolderThread(gate: Gate): Thread
30
val latch = new java.util.concurrent.CountDownLatch(1)
34
this.latch.countDown()
49
Thread.sleep(java.lang.Long.MAX_VALUE)
53
case ignore: InterruptedException => Thread.currentThread.interrupt
57
def time(code: => Unit) =
59
val before = System.currentTimeMillis
61
val after = System.currentTimeMillis
65
def spawn(code: => Unit) =
67
val result = new Thread
69
override def run = code
75
def assertReadersBlocked(code: => Unit)
77
this.assertReadSafety(threadSafe = true, 10L, TimeUnit.MILLISECONDS, code)
80
def assertReadersNotBlocked(code: => Unit)
82
this.assertReadSafety(threadSafe = false, 60L, TimeUnit.SECONDS, code)
85
def assertWritersBlocked(code: => Unit)
87
this.assertWriteSafety(threadSafe = true, 10L, TimeUnit.MILLISECONDS, code)
90
def assertWritersNotBlocked(code: => Unit)
92
this.assertWriteSafety(threadSafe = false, 60L, TimeUnit.SECONDS, code)
95
def assertReadSafety(threadSafe: Boolean, timeout: Long, timeUnit: TimeUnit, code: => Unit)
98
assertThreadSafety(timeout, timeUnit, gate, code, threadSafe, createReadLockHolderThread(gate))
101
def assertWriteSafety(threadSafe: Boolean, timeout: Long, timeUnit: TimeUnit, code: => Unit)
104
assertThreadSafety(timeout, timeUnit, gate, code, threadSafe, createWriteLockHolderThread(gate))
107
def assertThreadSafety(timeout: Long, timeUnit: TimeUnit, gate: ThreadSafetyTestTrait.this.type#Gate, code: => Unit, threadSafe: Boolean, lockHolderThread: Thread)
109
val millisTimeout = TimeUnit.MILLISECONDS.convert(timeout, timeUnit)
110
val measuredTime = time
112
// Don't start until the other thread is synchronized on classUnderTest
114
spawn(code).join(millisTimeout, 0)
118
"Measured " + measuredTime + " ms but timeout was " + millisTimeout + " ms.",
120
measuredTime >= millisTimeout)
122
lockHolderThread.interrupt()
123
lockHolderThread.join()