importjava.util.Map;importjava.util.concurrent.ConcurrentHashMap;importjava.util.concurrent.atomic.AtomicInteger;importorg.junit.Assert;importorg.junit.Test;/*** @Description: 测试Thread的方法*/
public classThreadMethodsTest {static String SLEEP = "sleep";static String YIELD = "yield";static String JOIN = "join";private Map map = new ConcurrentHashMap<>();class TheadSleep implementsRunnable {private intmillis;public TheadSleep(intmillis) {this.millis =millis;
}
@Overridepublic voidrun() {long threadId =Thread.currentThread().getId();
ThreadMethodEnum sleep=ThreadMethodEnum.SLEEP;
sleep.init(threadId);try{
Thread.sleep(millis);
}catch(InterruptedException e) {
e.printStackTrace();
}
sleep.stop();
map.put(sleep.getMethod(), sleep);
}
}class TheadYield implementsRunnable {
@Overridepublic voidrun() {long threadId =Thread.currentThread().getId();
ThreadMethodEnum yield=ThreadMethodEnum.YIELD;
yield.init(threadId);
Thread.yield();
yield.stop();
map.put(yield.getMethod(), yield);
}
}class TheadJoin implementsRunnable {privateThread thread;private int millis = 0;publicTheadJoin(Thread thread) {this.thread =thread;
}public TheadJoin(Thread thread, intmillis) {this.thread =thread;this.millis =millis;
}
@Overridepublic voidrun() {try{long threadId =Thread.currentThread().getId();
ThreadMethodEnum join=ThreadMethodEnum.JOIN;
join.init(threadId);if (millis > 0) {this.thread.join(millis);
}else{this.thread.join();
}
join.stop();
map.put(join.getMethod(), join);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}final AtomicInteger interruptCount = new AtomicInteger(0);final int interruptIndex = 100;class ThreadInterrupt extendsThread {
@Overridepublic voidrun() {while (!isInterrupted()) {
interruptCount.incrementAndGet();if (interruptCount.intValue() ==interruptIndex) {
interrupt();
}
}
}
}
@Testpublic void testSleep() throwsInterruptedException {int millis = 1000;
Thread sleep= new Thread(newTheadSleep(millis));
sleep.start();
sleep.join();
ThreadMethodEnum tme=map.get(SLEEP);//预期sleep时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 /millis));
}
@Testpublic void testYield() throwsInterruptedException {
Thread yield= new Thread(newTheadYield());
yield.start();
yield.join();
ThreadMethodEnum tme=map.get(YIELD);//预期yield消耗时间几乎为0
Assert.assertEquals(1, Math.round(tme.getStartTimeMillis() * 1.0 /tme.getStopTimeMillis()));
}
@Testpublic void testJoin() throwsInterruptedException {int millis = 1000;
Thread sleep= new Thread(newTheadSleep(millis));
sleep.start();
Thread join= new Thread(newTheadJoin(sleep));
join.start();
join.join();
ThreadMethodEnum tme=map.get(SLEEP);//预期sleep时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 /millis));
tme=map.get(JOIN);//预期join阻塞时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 /millis));
}
@Testpublic void testJoinMillis() throwsInterruptedException {int millis = 500;
Thread sleep= new Thread(new TheadSleep(millis * 2));
sleep.start();
Thread join= new Thread(newTheadJoin(sleep, millis));
join.start();
join.join();
ThreadMethodEnum tme=map.get(SLEEP);//预期sleep不能在join阻塞结束前设置,故为null
Assert.assertTrue(tme == null);
tme=map.get(JOIN);//预期join阻塞时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) /millis));
}
@Testpublic void testInterrupt() throwsInterruptedException {
ThreadInterrupt interrupt= newThreadInterrupt();
interrupt.start();
interrupt.join();
Assert.assertEquals(interruptIndex, interruptCount.intValue());
}
}enumThreadMethodEnum {
SLEEP(ThreadMethodsTest.SLEEP) {
@Overridepublic void init(longthreadId) {super.start(threadId);
}
},
YIELD(ThreadMethodsTest.YIELD) {
@Overridepublic void init(longthreadId) {super.start(threadId);
}
},
JOIN(ThreadMethodsTest.JOIN) {
@Overridepublic void init(longthreadId) {super.start(threadId);
}
};privateString method;private longthreadId;private longstartTimeMillis;private long stopTimeMillis = 0;privateThreadMethodEnum(String method) {this.method =method;
}public voidstop() {this.stopTimeMillis =System.currentTimeMillis();
}publicString getMethod() {returnmethod;
}public longgetThreadId() {returnthreadId;
}public longgetStartTimeMillis() {returnstartTimeMillis;
}public longgetStopTimeMillis() {returnstopTimeMillis;
}private void start(longthreadId) {this.threadId =threadId;this.startTimeMillis =System.currentTimeMillis();
}public abstract void init(longthreadId);
}