在Thread类提供的方法中,join方法和yield方法应该相对比较不好理解一点的,今天谈谈我的理解
join方法
首先看一下JDK中对于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);
}
Waits for this thread to die简单翻译过来就是等待当前线程死亡,其实是等到该线程一直运行结束的意思,也就是说当线程执行了join方法,那么该线程会一直占据处理器直到该线程运行结束。看下面一个示例:
private static class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(getName() + ":" + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
MyThread t1 = new MyThread("t1");
MyThread t2 = new MyThread("t2");
t1.start();
t1.join();
System.out.println("t1 is die: " + !t1.isAlive());
t2.start();
}
运行结果如下:

可以看到线程t1执行join方法之后一直占据着处理器,等到t1死亡之后其它线程才能获取到处理器使用权。另外join还有2个重载的方法

join(time)表示等待一定时间之后该线程放弃处理器独占权,该线程和其它线程并行执行,time时间之内该线程独占处理器。
yield方法
看一下JDK中对于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简单翻译过来就是该方法告诉调度器准备让出使用权,调度器也有可能会忽视。就是说yield方法是释放处理器使用权,让线程优先级更高或者同级的其它线程优先执行,但是调度器有可能还会继续调度该线程
看如下示例:
public static void main(String[] args) throws InterruptedException {
MyThread t1 = new MyThread("t1");
MyThread t2 = new MyThread("t2");
t1.start();
t2.start();
}
private static class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
if (getName().equals("t1")) {
yield();
}
System.out.println(getName() + ":" + i);
}
}
}
运行结果如下:

可以看到大部分时候线程t2是优先于t1运行的,就是线程t1让出了自己的优先处理权,但是也没有完全等到t2运行结束之后再运行,这是调度器还会调度到t1。
网友评论