Java线程不常用的方法
一、概述
Java线程中有些低频使用的方法,比如
- thread.join()
- thread.interupt()
- thread.yeild()
下文对这些方法进行简述
二、Thread.join()方法
按照官方解释,表示执行该方法的线程等待其执行结束。该方法是个重载方法:
| 方法 | 简述 |
|---|---|
| join() | 等待执行的线程执行结束 |
| join(long mill) | 等待执行的线程指定时间 |
| join(long mills ,long nanos) | 等待执行的线程指定的时间 |
本质上,以上三个方法的底层都是调用了Thread.wait()方法,该方法继承自Object。如下:
1.jpg
即本质上通过循环判断当前线程是否存活来完成。
2.1 Thread.join()应用场景
可以使用join()方法实现线程顺序执行完(注意是执行完)。
private static void threadSortJoin() throws InterruptedException {
// 预期希望按照 2 1 0 的顺序执行完
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 3; i++) {
threads.add(
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread : "+ Thread.currentThread().getName()+" is running.");
}
},"MyThread-"+i)
);
}
threads.get(2).start();
threads.get(2).join();
threads.get(1).start();
threads.get(1).join();
threads.get(0).start();
threads.get(0).join();
}
运行结果:
Thread : 2 is running.
Thread : 1 is running.
Thread : 0 is running.
三、线程中断-Thread.interupt()
线程有一个Interrupt标志字段,对象通过方法完成对该标志的赋值:
public void interrupt() {...}
// 重复执行两次该方法会抛:java.lang.IllegalMonitorStateException 异常
线程对象还可以通过调用以下方法来判断当前线程是否被打断:
public boolean isInterrupted() {...}
还有一个方法:判断线程是否被打断,若被打断后恢复其状态
/*
Tests whether the current thread has been interrupted.
The 【interrupted status】 of the thread is cleared by this method
*/
public boolean interrupted() {...} // 该方法本质上是调用到了JNI方法
2.jpg
3.jpg
当线程处于WAITING/TIMED_WAITING时,遇到线程中断,有以下表格响应中断异常:
| 状态 | 是否会触发异常 |
|---|---|
| WAITING(Object.wait()) | 是 |
| WAITING(thread.join()) | 是 |
| WAITING(LockSupport.park()) | 否 |
| TIMED-WAITING(Object.wait(int )) | 是 |
| TIMED-WAITING(thread.join(int)) | 是 |
| TIMED-WAITING(Thread.sleep(int)) | 是 |
| TIMED-WAITING(LockSupport.parkUntil()) | 否 |
四、线程让步-Thread.yield()
该方法首先是个JNI方法,如下:
public static native void yield();
Thread.yield()方法会通知线程调度器放弃对处理器的占用,但调度器可以忽视这个通知。其存在的目的在于保障线程间调度的连续性,防止某个线程一直长时间占用cpu资源。
该方法在JSL中未给出明确的语义,即具体实现由各个JVM各自实现。
部分JVM在执行这个函数时可能什么都不做,但是大部分jvm(比如HotSpot)的实现都是:
-
将线程从running状态转为runnable状态,
-
然后放入同优先级等待队列的末尾,等待前面所有相同优先级的线程调度完成后才可能再度获得执行机会
以上的第2点里,当同优先级队列中刚好只剩这个线程时,那么这个线程可能很快就又获得了cpu时间片。
以上说明,某线程中调用了该方法之后:
-
不一定马上停止执行(由running变为runable也需要系些时间)
-
有可能停止一会儿后又开始执行并且长时间运行(再次得到CPU时间片,得以执行)
但是他的使用应该基于详细的分析和测试。这个方法一般不推荐使用,它主要用于debug和测试程序,用来减少bug以及对于并发程序结构的设计。