预备知识:Java 线程挂起的常用方式有以下几种
Thread.sleep(long millis)
:这个方法可以让线程挂起一段时间,并释放 CPU 时间片,等待一段时间后自动恢复执行。这种方式可以用来实现简单的定时器功能,但如果不恰当使用会影响系统性能。Object.wait()
和Object.notify()
或Object.notifyAll()
:这是一种通过等待某个条件的发生来挂起线程的方式。wait()
方法会让线程等待,直到其他线程调用了notify()
或notifyAll()
方法来通知它。这种方式需要使用 synchronized 或者 ReentrantLock 等同步机制来保证线程之间的协作和通信。LockSupport.park()
和LockSupport.unpark(Thread thread)
:这两个方法可以让线程挂起和恢复。park()
方法会使当前线程挂起,直到其他线程调用了unpark(Thread thread)
方法来唤醒它。这种方式比较灵活,可以根据需要控制线程的挂起和恢复。
一:示例-引入主题
public class FutureTaskDemo {
public static void main(String[] args) {
FutureTask<String> futureTask = new FutureTask<>(new Callable() {
@Override
public Object call() throws Exception {
System.out.println("异步线程执行");
Thread.sleep(3000);//模拟线程执行任务需要3秒
return "ok";
}
});
Thread t1 = new Thread(futureTask, "线程一");
t1.start();
try {
//关键代码
String s = futureTask.get(2, TimeUnit.SECONDS); //最大等待线程2秒
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
二:进入futureTask.get(2, TimeUnit.SECONDS);
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING) //重点awaitDone,即完成了最大等待,依然没有结果就抛出异常逻辑
throw new TimeoutException();
return report(s);
}
awaitDone返回线程任务执行状态,即小于等于COMPLETING(任务正在运行,等待完成)抛出异常TimeoutException
三:进入(awaitDone(true, unit.toNanos(timeout)))原理分析
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
for (;;) {
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
int s = state;
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
else if (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) {
nanos = deadline - System.nanoTime();
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
LockSupport.parkNanos(this, nanos);
}
else
LockSupport.park(this);
}
}
3.1 总体解读awaitDone
利用自旋(for (;
标签:Thread,int,COMPLETING,state,源码,线程,NEW,FutureTask,等待时间 From: https://www.cnblogs.com/jinliang374003909/p/17264944.html