線程的狀態
操作系統的進程狀態分為: 就緒、運行中、阻塞、終止。阻塞狀態只能先變為就緒,再變為運行中。
public enum State {
/**
* Thread state for a thread which has not yet started.
* 線程還未啟動時的狀態。
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
* 可運行的狀態。處于可運行狀態的線程正在Java虛擬機中執行,
* 但它可能正在等待來自操作系統的其他資源,如處理器。
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
* 等待監視器鎖定的被阻塞線程的線程狀態。
* 處于阻止狀態的線程正在等待監視器鎖進入同步塊/方法,
* 或在調用Object.wait后重新進入同步塊/方法。
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* 等待線程的線程狀態。由于調用以下方法之一,線程處于等待狀態:
*
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
* 處于等待狀態的線程正在等待另一個線程執行特定操作。
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
* 例如:一個線程調用了一個對象上的Object.wait()方法,是在等待另外一個線程調用該對象的Object.notify或者Object.notifyAll()方法。
* 一個線程調用了Thread.join()是在等待一個特定的線程終止。
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* 具有指定等待時間的等待線程的線程狀態。
* 使用指定的等待時間調用以下方法會使一個線程處于TIMED_WAITING狀態:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
* 線程已終止。已完成執行。
*/
TERMINATED;
}
sleep方法
- 讓線程睡眠指定的毫秒數。
- sleep不會失去任何監視器的所有權。
- 可以被中斷。當被中斷并拋出異常時,線程的interrupted狀態會被清除。
/**
* 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.
* 如果任何線程中斷了該線程。當異常拋出時當前線程的interrupted狀態也將清除。
*/
public static native void sleep(long millis) throws InterruptedException;
join方法
- b線程內部調用a.join(),說明b要等待a線程終止后再繼續執行。
- a線程終止后,虛擬機底層會調用a.notifyAll方法將b喚醒。
- 可以被中斷。當被中斷并拋出異常時,線程的interrupted狀態會被清除。
/**
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
* 等待該線程死亡,最多等待millis毫秒。如果超時時間為0意味著永遠等待。
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
* 此實現使用this.isAlive循環調用this.wait。
* 當線程終止時,調用this.notifyAll方法。
* 不建議應用在Thread實例上使用 wait、notify、notifyAll。
*
* @param millis
* the time to wait 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.
* 如果任何線程中斷了該線程。當異常拋出時當前線程的interrupted狀態也將清除。
*/
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
yield方法
該方法就是說我讓出一下cpu的使用權,但是我還是就緒狀態,如果沒有其它競爭者獲得CPU,
CPU的執行權還是會給我,如果有其它競爭者獲得CPU,那么就先讓它執行。
/**
* 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.
* Yield是一種啟發式嘗試,旨在改善線程之間的相對進度,否則會過度使用CPU。
* 它的使用應該與詳細的分析和基準測試相結合,以確保它實際具有預期的效果。
*
* <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.
* 很少適合使用該方法。它可能對調試或測試有用,因為它可能有助于重現由于競爭條件而產生的bug。
* 在設計諸如{@link java.util.concurrent.locks}包中的并發控制結構時,它可能也很有用。
* 在ReentrantLock的內部類ConditionObject的transferAfterCancelledWait方法里就有使用。
*/
public static native void yield();
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.
* 除非當前線程中斷自身(這是始終允許的),否則將調用此線程的checkAccess方法,
* 這可能會導致拋出SecurityException。
*
* <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}.
* 如果在調用Object類的wait()、wait(long)或wait(long, int)方法時阻塞了該線程,
* 或者在該類的join()、join(long)、join(long, int)、sleep(long)、sleep(long, int)方法阻塞,
* 然后它的中斷狀態將被清除,它將收到一個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}.
* 如果此線程在java.nio.channels.interruptablechannel上的I/O操作中被阻塞,
* 然后通道將被關閉,線程的中斷狀態將被設置,線程將收到java.nio.channels.closedbyinteruptexception。
*
* <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.
* 如果該線程在ava.nio.channels.Selector中被阻塞,那么該線程的中斷狀態將被設置,
* 并且它將立即從選擇操作返回,可能帶有非零值,
* 就像調用了選擇器的java.nio.channels.Selector#wakeup方法一樣。
*
* <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();
}
/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
* 測試線程是否已經中斷。中斷狀態是否重置取決于傳遞的ClearInterrupted值。
*/
private native boolean isInterrupted(boolean ClearInterrupted);