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();
- 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.
翻譯: 提示系統調度器==當前線程==愿意放棄其正在使用的處理器資源.調度器可以忽略這個提示.(注:放棄正在使用的處理器資源也就表示一個線程將由運行狀態轉到就緒狀態,同時也說明此線程有可能會繼續被分配到處理器資源繼續執行)
靜態方法: 調用方式Thread.yield(); 從調用方式要理解的一個關鍵點是: 當前線程,那么這里的當前線程到底是哪個線程呢.比如我有代碼如下:
public class TestYield {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(){
@Override
public void run() {
try {
System.out.println("線程執行---");
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
System.out.println(System.currentTimeMillis());
thread.start();
Thread.yield();
System.out.println(System.currentTimeMillis());
}
}
當如上代碼執行的時候, Thread.yield()執行時,是哪個線程愿意放棄正在
使用的處理器資源呢,這里是主線程.也就是說Thread.yield()在哪個線程中被調用就
表示哪個線程愿意放棄處理器資源.
join()方法
join() : 當前線程暫停執行
/**
* Waits for this thread to die.
*
* <p> An invocation of this method behaves in exactly the same
* way as the invocation
*
* <blockquote>
* {@linkplain #join(long) join}{@code (0)}
* </blockquote>
*
* @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 final void join() throws InterruptedException {
join(0);
}
join(long millis): 當前線程暫停執行,直到millis毫秒之后繼續執行
/**
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
*
* <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.
*
* @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.
*/
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;
}
}
}
join(long millis, int nanos): 當前線程執行暫停, 直到millis+namos后繼續
/**
* Waits at most {@code millis} milliseconds plus
* {@code nanos} nanoseconds for this thread to die.
*
* <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.
*
* @param millis
* the time to wait in milliseconds
*
* @param nanos
* {@code 0-999999} additional nanoseconds to wait
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative, or the value
* of {@code nanos} is not in the range {@code 0-999999}
*
* @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 final synchronized void join(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
join(millis);
}
實例代碼:
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(){
@Override
public void run() {
try {
System.out.println("線程執行---");
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
System.out.println("開始:" + System.currentTimeMillis());
thread.start();
thread.join(3000);
System.out.println("結束:" + System.currentTimeMillis());
}
}
join()是實例方法, 只能在實例級別被調用, 那么在上述例子中,當執行thread.join()
方法時, 被暫停的是主線程還是thread線程呢? 結果是主線程被暫停. 也就是說被暫停
的線程還是調用執行這句代碼的線程.也就是說調用線程被暫停,而join()方法的所屬
實例繼續執行.如果join()方法不傳參數,那么主線程會等待直到thread線程執行完畢后
才會繼續執行,否則就是暫停傳入時間后繼續執行.
如果你想打斷這種暫停, 那么你可以在thread中調用notify(),notifyAll()方法來打斷.
但是就從注釋中我們也可以看出并不推薦在線程實例上條用notify()或者notifyAll()方法.
補充:從源碼中我們也可以看出join()方法其實是調用的Object的wait()方法來實現的,那么他又是在什么時候被notify的呢(我們知道被wait的線程必須被notify才會繼續執行).從注解(==As a thread terminates the
{@code this.notifyAll} method is invoked==)可知, 當一個線程終止時,他的notifyAll()方法會被調用