com.thesett.junit.concurrency.ThreadTestCoordinator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of junit-toolkit Show documentation
Show all versions of junit-toolkit Show documentation
JUnit Toolkit enhances JUnit with performance testing, asymptotic behaviour analysis, and concurrency testing.
/*
* Copyright The Sett Ltd, 2005 to 2014.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.thesett.junit.concurrency;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ThreadFactory;
import org.apache.log4j.Logger;
/**
* ThreadTestCoordinator provides an array of binary latches that allows threads to wait for other threads or to send
* them a signal that allows them to continue running or to wait for another thread to signal them. The binary latch
* array is always a square array, allowing one latch from and to every thread. Upon accepting an allow signal from one
* sender the latches for all senders for a are cleared. This class is always used in conjunction with
* {@link TestRunnable} for writing concurrent test code that coordinates multi-threaded activity in order to reproduce
* concurrency bugs.
*
*
CRC Card
* Responsibilities Collaborations
* Accept test threads to coordinate.
* Allow test threads to send 'allow to continue' signals.
* Allow test threads to wait on this coordinator for 'allow to continue' signals.
* Report error messages from test threads.
* Report exceptions from test threads.
* Provide method to wait until all test threads have completed.
*
*
* @author Rupert Smith
* @todo This code was hacked together as a bit of an experiment, because I wasn't sure if this idea would work. It
* has proved extremely usefull. Some documentation for this needs to be written to explain it better.
* @todo Consider how deadlock detection will be handled. If all threads are blocking on the coordinator, waiting for
* each other, they are deadlocked and there is something wrong with the test code that put them in that
* situation. If they are all blocked elsewhere, they may be deadlocked, or could just be waiting on some
* external event. A timeout should be used. Timeout is already implemented, just need to sanity check how this
* is working and document it.
* @todo Consider how livelock detection could be implemented? LockFree data structures might cause live locks. I
* guess a longish timeout is the only thing that can be done for that.
* @todo Only course grained synchronous at the method class level can be obtained. This is because test code can only
* insert synchronization points between method calls it makes. So this code will not be usefull for checking
* sequences of events within methods, unless the code under test is explicitly instrumented for it. It might be
* possible to instrument code by using labels, and then use the debugger/profiler interface to put breakpoints
* on the labels and use them as synchronization points. Not perfect, but at the unused labels can be left in
* the code, without altering its behaviour.
*/
public class ThreadTestCoordinator
{
/** Used for logging. */
private static final Logger log = Logger.getLogger(ThreadTestCoordinator.class);
/** Keeps track of the test threads by their ids. */
private final TestRunnable[] testThreads; // = new TestRunnable[2];
/** An explicit thread monitor for the coordinator. Threads wait on the coordinator whilst waiting for events. */
private final Object coordinatorLock = new Object();
/** A set of monitors for each test thread. */
private Object[] locks;
/** The binary latch array, this is always a square array allowing one event from and to every thread. */
private boolean[][] allowEvents;
/** Keeps track of the number of threads being coordinated. */
private int threadCount = 0;
/** Accumulates any exceptions resulting from the threads run methods. */
private final Collection© 2015 - 2024 Weber Informatics LLC | Privacy Policy