/*
授权声明:
本源码系《Java多线程编程实战指南(核心篇)》一书(ISBN:978-7-121-31065-2,以下称之为“原书”)的配套源码,
欲了解本代码的更多细节,请参考原书。
本代码仅为原书的配套说明之用,并不附带任何承诺(如质量保证和收益)。
以任何形式将本代码之部分或者全部用于营利性用途需经版权人书面同意。
将本代码之部分或者全部用于非营利性用途需要在代码中保留本声明。
任何对本代码的修改需在代码中以注释的形式注明修改人、修改时间以及修改内容。
本代码可以从以下网址下载:
https://github.com/Viscent/javamtia
http://www.broadview.com.cn/31065
*/
package util.stf;
import util.Tools;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@ConcurrencyTest
public class TestRunner {
private static final Semaphore FLOW_CONTROL = new Semaphore(Runtime
.getRuntime().availableProcessors());
private static final ExecutorService EXECUTOR_SERVICE = Executors
.newCachedThreadPool(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setPriority(Thread.MAX_PRIORITY);
t.setDaemon(false);
return t;
}
});
private volatile boolean stop = false;
private final AtomicInteger runs = new AtomicInteger(0);
private final int iterations;
private final int thinkTime;
private final Method publishMethod;
private final Method observerMethod;
private volatile Method setupMethod = null;
private final Object testCase;
private final SortedMap<Integer, ExpectInfo> expectMap;
public TestRunner(Method publishMethod, Method observerMethod,
Method setupMethod, Object testCase) {
this.publishMethod = publishMethod;
this.observerMethod = observerMethod;
this.setupMethod = setupMethod;
this.testCase = testCase;
this.expectMap = parseExpects(getExpects(observerMethod));
ConcurrencyTest testCaseAnn = testCase.getClass().getAnnotation(
ConcurrencyTest.class);
iterations = testCaseAnn.iterations();
thinkTime = testCaseAnn.thinkTime();
}
private static class ExpectInfo {
public final String description;
private final AtomicInteger counter;
public ExpectInfo(String description) {
this(description, 0);
}
public ExpectInfo(String description, int hitCount) {
this.description = description;
this.counter = new AtomicInteger(hitCount);
}
public int hit() {
return counter.incrementAndGet();
}
public int count() {
return counter.get();
}
}
public static void runTest(Class<?> testCaseClazz)
throws InstantiationException, IllegalAccessException {
Object test = testCaseClazz.newInstance();
Method publishMethod = null;
Method observerMethod = null;
Method setupMethod = null;
for (Method method : testCaseClazz.getMethods()) {
if (method.getAnnotation(Actor.class) != null) {
publishMethod = method;
}
if (method.getAnnotation(Observer.class) != null) {
observerMethod = method;
}
if (method.getAnnotation(Setup.class) != null) {
setupMethod = method;
}
}
TestRunner runner = new TestRunner(publishMethod, observerMethod,
setupMethod, test);
runner.doTest();
}
private static Expect[] getExpects(final Method observerMethod) {
Observer observerAnn = observerMethod.getAnnotation(Observer.class);
Expect[] expects = observerAnn.value();
return expects;
}
private static SortedMap<Integer, ExpectInfo> parseExpects(
final Expect[] expects) {
SortedMap<Integer, ExpectInfo> map = new ConcurrentSkipListMap<Integer, ExpectInfo>();
for (Expect expect : expects) {
map.put(Integer.valueOf(expect.expected()), new ExpectInfo(expect.desc()));
}
return map;
}
protected void doTest() {
Runnable publishTask = new Runnable() {
@Override
public void run() {
try {
publishMethod.invoke(testCase, new Object[] {});
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
FLOW_CONTROL.release(1);
}
}
};
Runnable observerTask = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
int result = -1;
try {
result = Integer.valueOf(observerMethod.invoke(testCase,
new Object[] {}).toString());
ExpectInfo expectInfo = expectMap.get(Integer.valueOf(result));
if (null != expectInfo) {
expectInfo.hit();
} else {
expectInfo = new ExpectInfo("unexpected", 1);
((ConcurrentMap<Integer, ExpectInfo>) expectMap).putIfAbsent(
result, expectInfo);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} finally {
FLOW_CONTROL.release(1);
}
}
};
CountDownLatch latch;
while (!stop) {
latch = createLatch();
if (null != setupMethod) {
try {
setupMethod.invoke(testCase, new Object[] {});
} catch (Exception e) {
break;
}
}
schedule(observerTask, latch);
schedule(publishTask, latch);
if (runs.incrementAndGet() >= iterations) {
break;
}
if (thinkTime > 0) {
Tools.randomPause(thinkTime);
}
try {
latch.await();
} catch (InterruptedException e) {
;
}
}
EXECUTOR_SERVICE.shutdown();
try {
EXECUTOR_SERVICE.awaitTermination(2000, TimeUnit.MINUTES);
} catch (InterruptedException e) {
;
}
report();
}
private static class DummyLatch extends CountDownLatch {
public DummyLatch(int count) {
super(count);
}
@Override
public void await() throws InterruptedException {
;
}
@Override
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return true;
}
@Override
public void countDown() {
;
}
@Override
public long getCount() {
return 0;
}
}
private CountDownLatch createLatch() {
CountDownLatch latch;
if (null != setupMethod) {
latch = new CountDownLatch(2);
} else {
latch = new DummyLatch(2);
}
return latch;
}
protected void report() {
ExpectInfo ei;
StringBuilder sbd = new StringBuilder();
sbd.append("\n\r<<Simple Concurrency Test Framework report>>:");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
sbd.append("\n\r===========================" + sdf.format(new Date())
+ "=================================");
for (Map.Entry<Integer, ExpectInfo> entry : expectMap.entrySet()) {
ei = entry.getValue();
sbd.append("\n\rexpected:" + entry.getKey() + " occurrences:"
+ ei.count() + " ==>" + ei.d
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
读书笔记:Java多线程编程实战指南核心篇.zip (176个子文件)
config 269B
FETCH_HEAD 134B
.gitignore 357B
HEAD 130B
HEAD 21B
pack-aedb30214c1fe6627c1e064847cf4a51e7a08a1d.idx 16KB
index 16KB
TestRunner.java 8KB
RecordProcessor.java 8KB
FileBatchUploader.java 7KB
Tools.java 6KB
XMLDocumentParser.java 4KB
BigFileDownloader.java 4KB
CaseRunner12_01.java 4KB
DESEncryption.java 3KB
DownloadTask.java 3KB
FileDownloaderApp.java 3KB
ShootPractice.java 3KB
SectionBasedStorageV2.java 3KB
SectionBasedStorageV1.java 3KB
MusicFinder.java 3KB
ConcurrentRSSReader.java 3KB
AlarmAgent.java 3KB
AbstractLoadBalancer.java 3KB
AbstractStatTask.java 3KB
ThreadMonitorDemo.java 3KB
DeadlockDetector.java 2KB
FalseSharingDemo.java 2KB
XThreadFactory.java 2KB
BuggyLckBasedPhilosopher.java 2KB
Debug.java 2KB
TerminatableTaskRunner.java 2KB
CASBasedCounter.java 2KB
XMLDocumentParserUsage.java 2KB
JITReorderingDemo.java 2KB
TimeoutWaitWithCondition.java 2KB
AbstractLogReader.java 2KB
Storage.java 2KB
MultithreadedStatTask.java 2KB
ScheduledTaskDemo.java 2KB
FineRequestRegistry.java 2KB
NaiveRequestRegistry.java 2KB
BigImmutableObject.java 2KB
FixedPhilosopher.java 2KB
TimeoutWaitExample.java 2KB
LogPrinterV2.java 2KB
FixedLockBasedPhilosopher.java 2KB
Configuration.java 2KB
ConfigurationHelper.java 2KB
WTSTMeasureDemo.java 2KB
DiningPhilosopherProblem.java 2KB
PeriodicTaskResultHandlingDemo.java 2KB
LogPrinterV1.java 2KB
Indicator.java 2KB
RaceConditionDemo.java 2KB
ThreadPauseDemo.java 2KB
NonAtomicAssignmentDemo.java 2KB
NestedMonitorLockoutDemo.java 2KB
TaskResultRetrievalDemo.java 2KB
TPBigFileDownloader.java 2KB
ServiceInvoker.java 2KB
ConfigurationManager.java 1KB
DownloadBuffer.java 1KB
Endpoint.java 1KB
WeightedRoundRobinLoadBalancer.java 1KB
FinalExample.java 1KB
AsyncTask.java 1KB
ConfigurationManagerV2.java 1KB
CaseRunner7_1.java 1KB
TaskRunner.java 1KB
ReadOnlyIterator.java 1KB
BrokenStatelessObject.java 1KB
EndpointView.java 1KB
SimpleStatTask.java 1KB
SampleServiceC.java 1KB
VolatileOrderingDemo.java 1KB
RecoverablePhilosopher.java 1KB
AbstractService.java 1KB
AppListener.java 1KB
JavaThreadAnywhere.java 1KB
ExchangerBasedLogReaderThread.java 1KB
ConcurrencyTest.java 1KB
VisibilityDemo.java 1KB
SystemBooter.java 1KB
HTTPRangeRequest.java 1KB
ServiceManager.java 1KB
Expect.java 1KB
Observer.java 1KB
FastTimeStampParser.java 1KB
RequestMessage.java 1KB
Actor.java 1KB
Setup.java 1KB
IncorrectDCLSingleton.java 1KB
RequestIDGenerator.java 1KB
ThreadSpecificSecureRandom.java 1KB
StaticVisibilityExample.java 1KB
SampleServiceB.java 1KB
SampleServiceA.java 1KB
SemaphoreBasedChannel.java 1KB
ReadWriteLockDowngrade.java 1KB
共 176 条
- 1
- 2
资源评论
九转成圣
- 粉丝: 5561
- 资源: 2962
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功