- 浏览: 51159 次
- 性别:
- 来自: JM&ZH&HK
文章分类
最新评论
-
jia22588:
[i][/i][/b][b][/b][b][flash=200 ...
java.lang.VerifyError, Incompatible argument to function -
Carterslam:
-agentlib:jdwp=transport=dt_soc ...
RCP remote debug -
deadcow:
好用啊,可以自己extend, 定义新的field,我主要用在 ...
Mule and QuickFIX/J integration -
hsbcnet:
hi, 您好.
我想问一下quickfixj好用吗, 你是 ...
Mule and QuickFIX/J integration -
Andyfai:
Hi, i would like to let you kno ...
New table from Nat Table based on SWT
整个Jar只有 4个class。
http://www.cs.umd.edu/projects/PL/multithreadedtc/overview.html
http://code.google.com/p/multithreadedtc/
1. What is MultithreadedTC?
MultithreadedTC is a framework for testing concurrent applications. It features a metronome that is used to provide fine control over the sequence of activities in multiple threads.
(OK I think I get it. Take me straight to some examples. )
Many failures in concurrent applications are not deterministic. They do not occur every time the application is run. Different interleavings of application threads yield different behaviors.
Concurrent application designers often want to run many (unrelated or loosely related) threads of activity to maximize throughput. Sometimes it is useful for test designers to mimic this style and run multiple threads, generating as many interleavings as possible. Many test frameworks support this paradigm (e.g. IBM's ConTest , GroboUtils' MultiThreadedTestRunner , and JUnit's ActiveTestSuite ).
MultithreadedTC is different. It supports test cases that exercise a specific interleaving of threads. This is motivated by the principle that concurrent applications should be built using small concurrent abstractions such as bounded buffers, semaphores and latches. Separating the concurrency logic from the rest of the application logic in this way makes it easier to understand and test concurrent applications. Since these abstractions are small, it should be possible to deterministically test every (significant) interleaving in separate tests.
But how can one guarantee a specific interleaving of different threads in the
presence of blocking and timing issues? Consider the following example of some operations
on a bounded blocking buffer (e.g. ArrayBlockingQueue
) with capacity 1:
We want a test to confirm that put 17
causes Thread 1 to block until
take 42
occurs in Thread 2. The
test must guarantee that take 42
is not executed until
after
put 17
. How could a designer guarantee this interleaving of
the two threads?
One approach is to use Thread.sleep()
in Thread 2 to delay its first
statement long enough to "guarantee" that Thread 1 has blocked. But this
approach makes the test timing-dependent ― timing can be thrown off by, say, an
ill-timed garbage collector. This also does not work well when stepping through
the code in a debugger.
Another common approach for coordinating activities in two threads is to use
a CountDownLatch.
A CountDownLatch
will not work in this example as illustrated
by the following pseudocode:
Initialization | |
ArrayBlockingQueue buf = new ArrayBlockingQueue(1);
|
|
Thread 1 | Thread 2 |
buf.put(42);
|
c.await();
|
Of course the problem is that the statement c.countDown()
cannot be executed
until after Thread 1 unblocks... which will not occur until Thread 2 take()
s. In
other words, this test is deadlocked!
MultithreadedTC provides an elegant solution to this problem, illustrated in the following example:
class
MTCBoundedBufferTest
extends
MultithreadedTestCase
{
|
This example is illustrated by the following diagram: |
Multithreaded has an internal metronome (or clock). But don't try and use it to set the tempo for your jazz band. The clock only advances to the next tick when all threads are blocked .
The clock starts at tick 0. In this example, the statement waitForTick(1)
makes Thread 2 block until the clock reaches tick 1 before resuming.
Thread 1 is allowed to run freely in tick 0, until it blocks on the call to put(17)
.
At this point, all threads are blocked, and the clock can advance to the next
tick.
In tick 1, the statement take(42)
in Thread 2 is executed, and this frees up Thread
1. The final statement in Thread 1 asserts that the clock is in tick 1, in
effect asserting that the thread blocked on the call to put(17)
.
This approach does not deadlock like the CountDownLatch
, and is more reliable
than Thread.sleep()
. Some other high level observations are:
- The test is encapsulated in a class that extends
MultithreadedTestCase
. Each of the threads is represented by a method whose name starts with "thread
", returnsvoid,
and has no arguments. Theinitialize()
method is invoked first; then the thread methods are invoked simultaneously in different threads; finally thefinish()
method is invoked when all threads have completed. - This test can be run using the following JUnit test:
public void testMTCBoundedBuffer () throws Throwable {
TestFramework.runOnce ( new MTCBoundedBufferTest () ) ;
}TestFramework
. TheTestFramework
creates the necessary threads, manages the metronome, and runs the test. - All the components of the test are represented using classes and methods, constructs that are recognizable to Java programmers.
- The framework handles exceptions thrown by any of the threads, and propagates them up to JUnit. This solves a problem with anonymous Threads, whose exceptions are not detected by JUnit without some extra scaffolding provided by the test designer. (See Examples 2 to 4 ).
- The clock is not necessarily incremented by units of one. When all threads
are blocked it advances to the next requested tick specified by a
waitForTick()
method. If none of the threads are waiting for a tick, the test is declared to be in deadlock (unless one of the threads is in stateTIMED_WAITING
).
2. So how does this work?
The class TestFramework
, provides most of the scaffolding required to run
MultithreadedTC
tests. It uses reflection to identify all relevant methods in
the test class, invokes them simultaneously in different threads. It regulates
these threads using a separate clock thread
.
The clock thread checks periodically to see if all threads are blocked. If
all threads are blocked and at least one is waiting for a tick, the clock thread
advances the clock to the next desired tick. The clock thread also detects
deadlock (when all threads are blocked, none are waiting for a tick, and none
are in state TIMED_WAITING
), and can stop a test that is going on too long (a
thread is in state RUNNABLE
for too long.)
The test threads are placed into a new thread group, and any threads created by these test cases will be placed in this thread group by default. All threads in the thread group will be considered by the clock thread when deciding whether to advance the clock, declare a deadlock, or stop a long-running test.
3. Cool! How do I use this?
MultithreadedTC tests are created by extending one of two classes:
- class
MultithreadedTestCase
extendsjunit.framework.Assert
and provides the base functionality required by all tests. (NOTE:MultithreadedTestCase
does NOT extendjunit.framework.TestCase
). A test using this class consists of:- an optional
initialize()
method, - one or more "thread" methods which are invoked in different threads,
- an optional
finish()
method that is run after all threads have completed.
MultithreadedTestCase
subclass, an additional JUnit test method is used to call one of the "run" methods inTestFramework
. The run methods receive an instance of aMultithreadedTestCase
and test it in different ways. The primary run methods are:-
runOnce(MultithreadedTestCase)
-- run a test sequence once, -
runManyTimes(MultithreadedTestCase, int)
-- run a test sequence as many times as specified by theint
parameter, until one of the test runs fails.
- an optional
- class
MultithreadedTest
extendsMultithreadedTestCase
and implementsjunit.framework.Test
. So it can be added to ajunit.framework.TestSuite
and run directly.
This class includes arunTest()
method that calls:TestFramework.runOnce(this)
. To change the way a test is run, override therunTest()
method.
(MultithreadedTC provides a convencience method:TestFramework.buildTestSuite(...)
, that looks for inner-classes that implementjunit.framework.Test
and builds aTestSuite
out of these classes.)
4. Some Examples of Test Cases
Example 1: Compare And Set
Here is a simple example to demonstrate the basic layout of a MultithreadedTC test. In this example, one thread stays in a while loop until its condition is met due to an action in another thread. Both threads are started simultaneously.
Notice that in the MultithreadedTC
version, the AtomicInteger
parameter is
initialized in the initialize()
method, not in a constructor. This is so that if
the test is run many times (with TestFramework.runManyTimes(...)
), a fresh
instance of AtomicInteger
is used each time.
This simple example demonstrates that MultithreadedTC takes care of much of the scaffolding work needed to set up and start a thread, and eliminates the need to join the thread before the test ends.
MultithreadedTC Version |
class
MTCCompareAndSet
extends
MultithreadedTest
{
|
Plain Version |
public
void
testCompareAndSet
()
throws
InterruptedException
{
|
Example 2: Interrupted Acquire
This example shows some of the strengths of MultithreadedTC
. An acquire()
on
a Semaphore
in one thread is expected to block, and throw an
InterruptedException
when interrupted by another thread.
The MultithreadedTC
version can assert that the
InterruptedException
is not
thrown until tick 1, which is when Thread 1 is interrupted. (So an
implementation of acquire that unconditionally throws the exception may pass the
plain version but will not pass the MultithreadedTC
version.)
waitForTick()
is used instead of Thread.sleep()
to eliminate timing dependencies.
Notice also that an unchecked AssertionError
(caused by the
fail(...)
statement in Thread 1) will cause the test to kill all threads and fail
immediately. In the plain version, this failure kills the auxillary thread but
not the test. Some extra work is needed to set a flag indicating thread failure,
and assert the flag in JUnit's tearDown()
method.
MultithreadedTC Version |
class
MTCInterruptedAcquire
extends
MultithreadedTestCase
{
|
Plain Version |
volatile
boolean
threadFailed;
|
MultithreadedTC
provides some convenience methods for getting access to a
thread. The call to getThread(n)
returns a reference to the thread running the
method threadn()
where n
is an integer. The more general method,
getThreadByName("threadMethod")
returns a reference to the thread running the
method threadMethod().
So getThread(1)
is equivalent to
getThreadByName("thread1")
.
Example 3: Thread Ordering
Most of the time, waitForTick()
is used to wait until another thread blocks,
as in Example 2. Occasionally though, it is useful for coordinating two or more
threads that do not contain any blocking. This example shows that even though,
the same can be accomplished using CountDownLatch
s, the MultithreadedTC
version
using waitForTick()
is easier to write and understand.
MultithreadedTC Version |
class
MTCThreadOrdering
extends
MultithreadedTestCase
{
|
CountDownLatch version |
volatile
boolean
threadFailed;
|
Example 4: Allowing Timeouts
Some concurrent abstractions rely on timing. An example is
the offer()
method on the ArrayBlockingQueue
,
which tries to add an element to the buffer and blocks for a
specified time limit if the buffer is full. If the offer()
times out, the method returns false
. This example
shows how waitForTick()
can interact with these
timing elements.
If the goal of the test is to cause a timeout in one thread,
we may want to prevent the clock from advancing in another
thread. MultithreadedTC provides the methods freezeClock()
and unfreezeClock()
, to respectively disable and
re-enable the clock thread. (The clock thread can still kill a
test that is running for too long when it is disabled.)
In this test, the first offer()
is allowed to timeout, the second
offer()
is interrupted. To guarantee that the
interrupt does not occur on the first offer()
, it uses
freezeClock()
to freeze the clock during the first offer. Thread 2 is
awakened when Thread 1 blocks on the second offer()
.
(Note that the timeout in the offer()
statement
should be much longer than the clock period (see
Javadoc
) to ensure that the clock thread has a chance to
wake up.) Obviously tests like this that inherently include
timing do not play well in a debugger.
MultithreadedTC Version |
class
MTCTimedOffer
extends
MultithreadedTestCase
{
|
Plain Version |
volatile
boolean
threadFailed;
|
发表评论
-
line separator in java
2009-12-04 11:35 950http://en.wikipedia.org/wiki/Ne ... -
FAST(FIX Adapted for STreaming)
2009-11-23 12:09 1663FIX Adapted for STreaming : ... -
thinking in java
2009-07-01 16:43 769just for back up -
view java src code and examples online
2009-07-01 16:32 814http://kickjava.com/ src code ... -
QuickFIXJ Notes
2009-06-23 22:35 12251. Session: a).config the ... -
Build OSGi bundle using maven
2009-02-16 15:23 951https://mail.osgi.org/pipermail ... -
Open Source PageFlow (a.k.a. State Machine) Writte
2008-07-16 14:45 1771转载:http://www.manageability.org ...
相关推荐
for MTL in Deep Learning, gives an overview of the literature, and discusses recent advances. In particular, it seeks to help ML practitioners apply MTL by shedding light on how MTL works and ...
Overview of data mining. Emphasis is placed on basic data mining concepts. Techniques for uncovering interesting data patterns hidden in large data sets.
unit 1 overview of IT industry
Overview of the OMG Data Distribution Service
Overview of the System Engineering Process System Engineering 系统工程 信息化 ERP 大数据
An overview of gradient descent optimization algorithms
A Technical Overview of VP9--the Latest Open-Source Video Codec Google has recently finalized a next generation open-source video codec called VP9, as part of the libvpx repository of the WebM project...
overview of MTL by first giving a definition of MTL. Then several different settings of MTL are introduced, including multi-task supervised learning, multi-task unsupervised learning, multi-task semi...
its results, and then vanished back under the same cloak of secrecy under which it had been developed. Now for the first time, details of the architecture and algorithms can be revealed.
If Alice and Bob each know their own private key and the other's public key, they can communicate securely, through any number of public key based protocols such as IPSec, PGP, S/MIME, or SSL....
该文件为CCSDS发布的《空间通信协议概览》(Overview of Space Communications Protocols),版本号为CCSDS 130.0-G-2,属于绿色手册系列,发布日期为2007年12月。该文档作为一份信息报告,详细介绍了由CCSDS推荐的...
static_assert(sizeof(int) == 4, "Size of int must be 4 bytes"); ``` **优点:** - **错误检测**:能够在编译期间捕获错误,而不是运行时。 - **性能优化**:避免了运行时检查,提高了程序的执行效率。 #### 六...
Abstract: Servlet program running in the server-side, dynamically generated Web page with the traditional CGI and many other similar compared to CGI technology, Java Servlet with a more efficient, ...
HEVC/H.265标准综述文章 视频编码,算法,H.264/AV1 Inter prediction Intra prediciton Overview High efficiency video coding (HEVC) standard PDF
The RANdom SAmple Consensus (RANSAC) algorithm proposed by Fischler and Bolles [1] is a general parameter estimation approach designed to cope with a large proportion of outliers in the input data....
Liu Yang撰写的文章《An Overview of Distance Metric Learning》是一篇经典的度量学习综述论文,它对度量学习领域内的问题进行了分类,并详细总结了每类问题下现有的工作及其本质联系、优势和不足。 文章首先介绍...
Overview of DriverStudio Tools
### 新版C++(C++0x)概览 #### 背景介绍与文档概述 此文档由著名软件开发顾问Scott Meyers撰写,旨在为读者提供新版C++(即C++0x,后更名为C++11)的全面概览。这份资料最初发布于2010年4月5日,并在2011年4月30...