日常小记|面试官:请你设计一个任务执行超时退出的接口!

    科技2025-08-14  27

    文章目录

    前言思路总结

    前言

    这是蘑菇街一面面试官问我的一个问题。他说:如果有这么一个场景,我执行业务的时候,不想让业务执行时间超过一定时间,如果超出就停止执行,你怎么来设计!

    思路

    我们在学习Java并发编程的时候,那些常见的方法大多都有设置超时时间的参数,我们可以根据这一思路来设计超时结束任务的方案。我这里用到的是Thread.join()方法,先来解释下join方法吧。

    join()方法:如果一个线程A执行了thread.join()语句,其含义是:当前线程A等待thread线程终止之后才从thread.join()返回。线程Thread除了提供join()方法之外,还提供了join(long millis)和join(long millis,int nanos)两个具备超时特性的方法。这两个超时方法表示,如果线程thread在给定的超时时间里没有终止,那么将会从该超时方法中返回。摘自《Java并发编程的艺术》

    我们来看下join的源码:

    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 { //正常来说,我们会进入到这里,进入到循环里,直到调用join方法的线程执行完毕之后或者超出时间限制了,才退出。 while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }

    其实我感觉书中对join的解释还是有那么一点欠缺的,我认为是:当在主线程A中调用另一个线程B的join方法意味着,从一开始的A、B两个线程并发执行变为串行执行的了,也就是将B线程插入到A线程中,然后等待B线程执行完成以后,再执行剩下的A线程的任务了。如果这个join方法带有超时参数的话,可以理解为,在这段时间内,A等待B线程执行(串行),一旦超出这个时间,两个线程又会回到并发执行的状态了。

    回到我们之前的问题 ,我们想设计一个超时退出的接口,就可以利用这个带有超时参数的join来实现,来看看我的代码,注意看注释。

    package com.markus.basic.Java多线程.方法超时问题; /** * Author:markusZhang * Date:Create in 2020/10/8 12:57 * todo: */ public class JoinDemo { public static void main(String[] args){ Thread method = new Thread(new ThreadMethod()); //调用方法 method.start(); try { method.join(2000);//规定业务接口执行不能超过的时长 } catch (InterruptedException e) { e.printStackTrace(); } method.interrupt();//调用中断很重要,如果不调用的话,就会回到上面说的,两个线程并发执行,就起不到效果了。 } } class ThreadMethod implements Runnable{ @Override public void run() { try { Thread.sleep(3000);//执行业务 System.out.println("方法调用完成"); } catch (InterruptedException e) { //e.printStackTrace(); System.out.println("方法调用超时"); } } }

    总结

    当然了,设计任务执行超时退出有很多种方案,这个只是其中一种。在开发中,我们需要多注意下那些带有超时参数的方法,说不定也是可以设计的。

    Processed: 0.010, SQL: 9