美文网首页
多线程超时处理

多线程超时处理

作者: zcoljefe | 来源:发表于2018-01-16 16:43 被阅读0次

背景:多个线程同时执行某一类任务,在规定时间内未完成,则终止未完成的线程继续执行,防止系统资源的浪费和用户的长时间等待,并获取已完成线程的返回结果。
方案:使用计数器 CountDownLatch 的 await(long timeout, TimeUnit unit) 方法。

public class Main {
    /* 启动线程数 */
    private static final int THREAD_COUNT = 10; 

    public static void main(String[] args) {
        /* 线程池 */
        ExecutorService ex = Executors.newFixedThreadPool(THREAD_COUNT);
        /* 计数器 */
        CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
        List<Future<String>> tasks = new ArrayList<>();
        /* 启动 THREAD_COUNT 子线程 */
        IntStream.range(0, THREAD_COUNT).forEach(i -> tasks.add(ex.submit(() -> planThread(i, latch))));
        /* 启动监听线程 */
        new Thread(() -> timoutListener(latch, 5000, tasks)).start();
        //主线程处理其它任务......
        /* 获取多线程处理结果 */
        for (int i = 0; i < tasks.size(); i++) {
            Future<String> f = tasks.get(i);
            try {
                System.out.println("Main线程:Thread 【" + i + "】返回:" + f.get());
            }  catch (Exception e) {
                System.out.println("Main线程:Thread 【" + i + "】被取消,无返回结果");
            }
        }
        ex.shutdown();
    }

    /* 任务处理线程 */
    private static String planThread(int i, CountDownLatch latch) {
        try {
            System.out.println("===线程" + i + "开始执行");
            String s = "";
            int m = 0;

            while(m < Integer.MAX_VALUE){
                if(Thread.currentThread().isInterrupted()){
                    System.out.println("线程被中断");
                    return null;
                }
                if(m%10000 == 0){
                    System.out.println(m);
                }
                s += m;
                m ++;
            }
            latch.countDown();
            System.out.println("线程" + i + "执行时完成===");
            return "" + i;
        } catch(CancellationException e){
            e.printStackTrace();
        }
        return null;
    }

    /* 超时监听线程 */
    public static void timoutListener(CountDownLatch latch, long timeOutMillion, List<Future<String>> tasks){
        try {
            /* 如果计数器为0(所有任务完成)或超过时间,则向下执行 */
            latch.await(timeOutMillion, TimeUnit.MILLISECONDS);
            for (int i = 0; i < tasks.size(); i++) {
                Future<String> f = tasks.get(i);
                if (!f.isDone()) {
                    System.out.println("监听线程:终止Thread 【" + i + "】");
                    f.cancel(true);
                } else {
                    System.out.println("监听线程:Thread 【" + i + "】已正常结束");
                }
            }
            System.out.println("监听线程结束!");
        } catch (InterruptedException e) {
            System.out.println("监听线程抛出中断异常");
        }
    }
}

另外:
Future 的 get(long timeout, TimeUnit unit) 方法:是在调用 get 方法时开始记时,等待指定时间,并非是从任务开始计时。并且等待第一个线程超时后,第二线程个调用 get 重新计时,无法保证所有线程在指定时间内完成。
CyclicBarrier 的 await(long timeout, TimeUnit unit) 用于一个子线程等待其它子线程的时间,主要用于线程间同步。

相关文章

  • 多线程超时处理

    背景:多个线程同时执行某一类任务,在规定时间内未完成,则终止未完成的线程继续执行,防止系统资源的浪费和用户的长时间...

  • 超时处理

  • 基于时间轮片方式处理超时任务

    基于时间轮片方式处理超时任务基于时间轮片方式处理超时任务

  • golang执行外部命令超时处理

    golang执行外部命令超时处理 不至于当前程序挂起,超时杀死超时进程。

  • 重写jquery的ajax方法

    session超时处理示例:

  • js超时处理

    var lastTime = new Date().getTime(); var currentTime ...

  • 链接超时处理

    一般我们都会碰到链接超时的情况导致程序无法运行,这里我们就直接将链接时间增加不就可以了嘛。找到tomcat服务器,...

  • php超时处理

    1.Apache一般在性能很高的情况下,缺省所有超时配置都是30秒,但是在上传文件,或者网络速度很慢的情况下,那么...

  • 多线程批量导入数据

    如何用多线程批量导入数据?最近的使用场景就是批量导入excel数据,数据量太大的话会导致超时、服务异常超时等问题。...

  • 多线程处理数据

    多线程处理数据

网友评论

      本文标题:多线程超时处理

      本文链接:https://www.haomeiwen.com/subject/uunsoxtx.html