標籤:標記 over integer org 結束 ext span exception while
Thread實現Runnable介面並實現了大量實用的方法
public static native void yield();
此方法釋放CPU,但並不釋放已獲得的鎖,其它就緒的線程將可能得到執行機會,它自己也有可能再次得到執行機會
public static native void sleep(long millis) throws InterruptedException;
此方法釋放CPU,但並不釋放已獲得的鎖,其它就緒的線程將得到執行機會,在休眠時間結束後,當前線程繼續執行
public final void join() throws InterruptedException;
一旦調用後宿主線程將阻塞,待當前線程結束後繼續
public final synchronized void join(long millis)throws InterruptedException;
一旦調用後宿主線程將阻塞,待millis時間結束後繼續
public void interrupt();
中斷線程
public final void setDaemon(boolean on);
on=true表示線程標記為守護線程(例如GC線程),若正在啟動並執行所有線程都是守護線程,JVM將退出
import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.atomic.AtomicInteger;import org.junit.Assert;import org.junit.Test;/** * @Description: 測試Thread的方法 */public class ThreadMethodsTest { static String SLEEP = "sleep"; static String YIELD = "yield"; static String JOIN = "join"; private Map<String, ThreadMethodEnum> map = new ConcurrentHashMap<>(); class TheadSleep implements Runnable { private int millis; public TheadSleep(int millis) { this.millis = millis; } @Override public void run() { 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 implements Runnable { @Override public void run() { long threadId = Thread.currentThread().getId(); ThreadMethodEnum yield = ThreadMethodEnum.YIELD; yield.init(threadId); Thread.yield(); yield.stop(); map.put(yield.getMethod(), yield); } } class TheadJoin implements Runnable { private Thread thread; private int millis = 0; public TheadJoin(Thread thread) { this.thread = thread; } public TheadJoin(Thread thread, int millis) { this.thread = thread; this.millis = millis; } @Override public void run() { 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 extends Thread { @Override public void run() { while (!isInterrupted()) { interruptCount.incrementAndGet(); if (interruptCount.intValue() == interruptIndex) { interrupt(); } } } } @Test public void testSleep() throws InterruptedException { int millis = 1000; Thread sleep = new Thread(new TheadSleep(millis)); sleep.start(); sleep.join(); ThreadMethodEnum tme = map.get(SLEEP); // 預期sleep時間與millis相近 Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 / millis)); } @Test public void testYield() throws InterruptedException { Thread yield = new Thread(new TheadYield()); yield.start(); yield.join(); ThreadMethodEnum tme = map.get(YIELD); // 預期yield消耗時間幾乎為0 Assert.assertEquals(1, Math.round(tme.getStartTimeMillis() * 1.0 / tme.getStopTimeMillis())); } @Test public void testJoin() throws InterruptedException { int millis = 1000; Thread sleep = new Thread(new TheadSleep(millis)); sleep.start(); Thread join = new Thread(new TheadJoin(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)); } @Test public void testJoinMillis() throws InterruptedException { int millis = 500; Thread sleep = new Thread(new TheadSleep(millis * 2)); sleep.start(); Thread join = new Thread(new TheadJoin(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)); } @Test public void testInterrupt() throws InterruptedException { ThreadInterrupt interrupt = new ThreadInterrupt(); interrupt.start(); interrupt.join(); Assert.assertEquals(interruptIndex, interruptCount.intValue()); }}enum ThreadMethodEnum { SLEEP(ThreadMethodsTest.SLEEP) { @Override public void init(long threadId) { super.start(threadId); } }, YIELD(ThreadMethodsTest.YIELD) { @Override public void init(long threadId) { super.start(threadId); } }, JOIN(ThreadMethodsTest.JOIN) { @Override public void init(long threadId) { super.start(threadId); } }; private String method; private long threadId; private long startTimeMillis; private long stopTimeMillis = 0; private ThreadMethodEnum(String method) { this.method = method; } public void stop() { this.stopTimeMillis = System.currentTimeMillis(); } public String getMethod() { return method; } public long getThreadId() { return threadId; } public long getStartTimeMillis() { return startTimeMillis; } public long getStopTimeMillis() { return stopTimeMillis; } private void start(long threadId) { this.threadId = threadId; this.startTimeMillis = System.currentTimeMillis(); } public abstract void init(long threadId);}
Java多線程系列二——Thread類的方法