java多執行緒2:Thread中的方法
靜態方法:
Thread類中的靜態方法表示操作的執行緒是"正在執行靜態方法所在的程式碼塊的執行緒"。
為什麼Thread類中要有靜態方法,這樣就能對CPU當前正在執行的執行緒進行操作。下面來看一下Thread類中的靜態方法:
1:currentThread
/** * Returns a reference to the currently executing thread object. * * @return the currently executing thread. */ public static native Thread currentThread();
currentThread()方法返回的是對當前正在執行執行緒物件的引用。
/** * 測試Thread.currentThread():返回程式碼段正在被哪個執行緒呼叫的資訊 * this 始終表示執行緒例項本身 * * @author yuxiaoyu */ public class Mythread4 extends Thread { static { System.out.println("Mythread4靜態塊的列印:Thread.currentThread().getName()=" + Thread.currentThread().getName()); } public Mythread4() { System.out.println("Mythread4構造方法:Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Mythread4構造方法:this.getName()=" + this.getName()); } public void run() { System.out.println("run 方法:Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("run 方法:this.getName()=" + this.getName()); } }
@Test public void test4() { Mythread4 a = new Mythread4(); a.start(); }
執行結果:
Mythread4靜態塊的列印:Thread.currentThread().getName()=main Mythread4構造方法:Thread.currentThread().getName()=main Mythread4構造方法:this.getName()=Thread-0 run 方法:Thread.currentThread().getName()=Thread-0 run 方法:this.getName()=Thread-0
這個結果說明,執行緒類的構造方法、靜態塊是被main執行緒呼叫的,而執行緒類的run()方法才是應用執行緒自己呼叫的,this 始終表示執行緒例項本身。
2:sleep
/** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds, subject to * the precision and accuracy of system timers and schedulers. The thread * does not lose ownership of any monitors. * * @param millis * the length of time to sleep in milliseconds * * @throws IllegalArgumentException * if the value of {@code millis} is negative * * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ public static native void sleep(long millis) throws InterruptedException;
該方法是讓正在執行的線路休眠指定毫秒,注意API的註釋中“The thread does not lose ownership of any monitors.”表示執行緒不會失去任何監視器的所有權。
簡單說就是sleep程式碼上下文如果被加鎖了,那麼在休眠的時間內,鎖依然在,但是CPU資源會讓出給其他執行緒。
3:yield
/** * A hint to the scheduler that the current thread is willing to yield * its current use of a processor. The scheduler is free to ignore this * hint. * * <p> Yield is a heuristic attempt to improve relative progression * between threads that would otherwise over-utilise a CPU. Its use * should be combined with detailed profiling and benchmarking to * ensure that it actually has the desired effect. * * <p> It is rarely appropriate to use this method. It may be useful * for debugging or testing purposes, where it may help to reproduce * bugs due to race conditions. It may also be useful when designing * concurrency control constructs such as the ones in the * {@link java.util.concurrent.locks} package. */ public static native void yield();
該方法表示給排程程式的一個提示:當前執行緒願意讓出它當前對處理器的使用。排程程式可以自由地忽略這個提示。
public class Mythread5 extends Thread { public void run() { long beginTime = System.currentTimeMillis(); int count = 0; for (int i = 0; i < 50000000; i++) { Thread.yield(); count = count + i + 1; } long endTime = System.currentTimeMillis(); System.out.println("用時:" + (endTime - beginTime) + "毫秒!"); } }
第一次執行結果:用時:34872毫秒!
第二次執行結果:用時:33738毫秒!
如果將Thread.yield(); 註釋掉的話,執行結果:用時:48毫秒!。
看到,每次執行的用時都不一樣,證明了yield()方法放棄CPU的時間並不確定,而且yield方法將CPU資源讓給其他資源導致變慢。
4:interrupted()
/** * Tests whether the current thread has been interrupted. The * <i>interrupted status</i> of the thread is cleared by this method. In * other words, if this method were to be called twice in succession, the * second call would return false (unless the current thread were * interrupted again, after the first call had cleared its interrupted * status and before the second call had examined it). * * <p>A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return <code>true</code> if the current thread has been interrupted; * <code>false</code> otherwise. * @see #isInterrupted() * @revised 6.0 */ public static boolean interrupted() { return currentThread().isInterrupted(true); }
/** * Tests if some Thread has been interrupted. The interrupted state * is reset or not based on the value of ClearInterrupted that is * passed. */ private native boolean isInterrupted(boolean ClearInterrupted);
測試當前執行緒是否已經中斷,並清除執行緒的中斷狀態。
例項方法
1:start
/** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * <p> * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception IllegalThreadStateException if the thread was already * started. * @see #run() * @see #stop() */ public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }
此方法告訴執行緒執行器,這個執行緒可以執行了。
2:isAlive
/** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * * @return <code>true</code> if this thread is alive; * <code>false</code> otherwise. */ public final native boolean isAlive();
判斷當前的執行緒是否處於活動狀態,活動狀態就是執行緒已經啟動且尚未終止。執行緒處於正在執行或準備開始執行的狀態,就認為執行緒是“存活”的。
public class Mythread7_2 extends Thread { public Mythread7_2() { System.out.println("Mythread7_2---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("Mythread7_2---end"); } @Override public void run() { System.out.println("run---begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("run---end"); } }
@Test public void test7_2() { Mythread7_2 c = new Mythread7_2(); System.out.println("main begin t1 isAlive=" + c.isAlive()); c.setName("A"); c.start(); System.out.println("main end t1 isAlive=" + c.isAlive()); }
執行結果:
Mythread7_2---begin Thread.currentThread().getName()=main Thread.currentThread().isAlive()=true this.getName()=Thread-0 this.isAlive()=false Mythread7_2---end main begin t1 isAlive=false run---begin Thread.currentThread().getName()=A Thread.currentThread().isAlive()=true this.getName()=A this.isAlive()=true run---end main end t1 isAlive=false
可以看出:只有在當前例項物件呼叫了start方法時,this.isAlive()才返回true。
3:interrupt
/** * Interrupts this thread. * * <p> Unless the current thread is interrupting itself, which is * always permitted, the {@link #checkAccess() checkAccess} method * of this thread is invoked, which may cause a {@link * SecurityException} to be thrown. * * <p> If this thread is blocked in an invocation of the {@link * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link * Object#wait(long, int) wait(long, int)} methods of the {@link Object} * class, or of the {@link #join()}, {@link #join(long)}, {@link * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, * methods of this class, then its interrupt status will be cleared and it * will receive an {@link InterruptedException}. * * <p> If this thread is blocked in an I/O operation upon an {@link * java.nio.channels.InterruptibleChannel InterruptibleChannel} * then the channel will be closed, the thread's interrupt * status will be set, and the thread will receive a {@link * java.nio.channels.ClosedByInterruptException}. * * <p> If this thread is blocked in a {@link java.nio.channels.Selector} * then the thread's interrupt status will be set and it will return * immediately from the selection operation, possibly with a non-zero * value, just as if the selector's {@link * java.nio.channels.Selector#wakeup wakeup} method were invoked. * * <p> If none of the previous conditions hold then this thread's interrupt * status will be set. </p> * * <p> Interrupting a thread that is not alive need not have any effect. * * @throws SecurityException * if the current thread cannot modify this thread * * @revised 6.0 * @spec JSR-51 */ public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interrupt0(); // Just to set the interrupt flag b.interrupt(this); return; } } interrupt0(); }
interrupt並不會立刻停止執行緒,interrupt0的作用僅僅是為當前執行緒打一箇中斷的標誌。
4:isInterrupted
/** * Tests whether this thread has been interrupted. The <i>interrupted * status</i> of the thread is unaffected by this method. * * <p>A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return <code>true</code> if this thread has been interrupted; * <code>false</code> otherwise. * @see #interrupted() * @revised 6.0 */ public boolean isInterrupted() { return isInterrupted(false); }
測試執行緒是否已經中斷,但不清除狀態標識。這個和interrupted()方法區別就是不清除狀態標識。
參考文獻
1:《Java併發程式設計的藝術》
2:《Java多執行緒程式設計核心技術》
==================================================================
勇氣是,儘管你感到害怕,但仍能迎難而上。
儘管你感覺痛苦,但仍能直接面對。
向前一步,也許一切都會不同。
==================================================================