如果线程中的执行时间过长,导致长时间被占用,可以通过新建一个子线程,来监控主线程的执行超时时间,如果超时了,通过子线程杀掉父线程 (主意,父线程被杀后,子线程还会活着) 子线程杀掉主线程

这个问题其实还是没有搞定。下面的代码只是发起了线程的中断,某一行代码执行结束后,不会执行后续的代码。但就这某一行卡住了的话,本方案还是无解的。

package com.vipsoft.Thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger; public class ThreadPoolExecutorTest { public static void main(String[] args) throws Exception {
int corePoolSize = 2;
int maximumPoolSize = 5;
long keepAliveTime = 10;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(3); //定义一个大小为2的队列,只等有一个任务在排队等,多出来的需要开新线程
ThreadFactory threadFactory = new MyTreadFactory();
RejectedExecutionHandler handler = new MyPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
System.out.println("预启动线程(备战)");
executor.prestartAllCoreThreads(); // 预启动所有核心线程,处于备战
System.out.println("预启动线程数(备战):" + executor.getPoolSize());
for (int i = 1; i <= 10; i++) {
System.out.println(System.currentTimeMillis() + " " + "开始 下发任务:" + i + " 当前线程总数:" + executor.getPoolSize());
MyTask task = new MyTask(String.valueOf(i));
executor.execute(task);
System.out.println(System.currentTimeMillis() + " " + "完成 下发任务:" + i + " 当前线程总数:" + executor.getPoolSize() + " 队列中的线程数量:" + workQueue.size());
Thread.sleep(1); //停1毫秒,日志记录,时间后方便分析
if (i == 9) {
//TODO Thread.sleep(3000); //任务9下发后【会被拒绝】,停3秒,等队列或线程释放后,再下发任务10,这时候任务10不会被拒绝
}
}
System.in.read(); //阻塞主线程
} static class MyTreadFactory implements ThreadFactory { private final AtomicInteger mThreadNum = new AtomicInteger(1); @Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "Thread-" + mThreadNum.getAndIncrement());
System.out.println(System.currentTimeMillis() + " " + t.getName() + " has been created");
return t;
}
} public static class MyPolicy implements RejectedExecutionHandler { public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 可做日志记录等
System.err.println(System.currentTimeMillis() + " " + r.toString() + " rejected from " + e.toString());
}
} static class MyTask implements Runnable {
private String name; public MyTask(String name) {
this.name = name;
} @Override
public void run() {
try {
Thread mainT = Thread.currentThread();
String taskName = this.name;
SubThread st = new SubThread(taskName, mainT);
Thread thread = new Thread(st);
thread.start();
try {
long millis = 1000;
if (Integer.valueOf(taskName) % 2 == 0) {
millis = Integer.valueOf(taskName) * 2 * millis; //让任务执行慢点
}
System.out.println(System.currentTimeMillis() + " " + this.toString() + " 开始运行! 运行线程 " + Thread.currentThread().getName() + " 需要(秒):" + millis);
Thread.sleep(millis); //让任务执行慢点--这边还是有点问题,如果这个 sleep 过长的话,还是需要等它执行完,并不能解决线程超时杀掉它的目的
System.out.println(System.currentTimeMillis() + " " + this.toString() + " 运行结束! 运行线程 " + Thread.currentThread().getName());
} catch (InterruptedException e) {
System.out.println(System.currentTimeMillis() + " " + this.toString() + " 被打断 运行线程 " + Thread.currentThread().getName());
} finally {
st.setDone(); //通知监控线程,主线程运行结束
//TODO thread.interrupt(); //父线程也可以中止子线程的任务执行
} } catch (Exception e) {
e.printStackTrace();
}
} @Override
public String toString() {
return "MyTask [name=" + this.name + "]";
} static class SubThread implements Runnable {
private String name;
private Thread mainT; //如果完成了就不用杀了。
private boolean isDone; public void setDone() {
isDone = true;
} public SubThread(String name, Thread mainT) {
this.name = name;
this.mainT = mainT;
} @Override
public void run() {
try {
System.out.println(System.currentTimeMillis() + " 子线程 " + Thread.currentThread().getName() + "【正在】监控主进程 " + mainT.getName() + " 任务" + name);
Thread.sleep(5000);
//时间到了,主线程还没有完成就干掉。
if (!isDone) {
mainT.interrupt();
System.out.println(System.currentTimeMillis() + " 子线程 " + Thread.currentThread().getName() + "【杀掉】主进程(超时了) " + mainT.getName() + " 任务" + name);
}
} catch (InterruptedException e) {
System.out.println(System.currentTimeMillis() + " 子线程 " + Thread.currentThread().getName() + "【被打断】" + mainT.getName() + " 任务" + name);
} finally {
System.out.println(System.currentTimeMillis() + " 子线程 " + Thread.currentThread().getName() + "【完成】监控主进程 " + mainT.getName() + " 任务" + name);
}
} @Override
public String toString() {
return "MyTask [name=" + this.name + "]";
}
}
} }

日志排序后:

1655083181083  Thread-1 has been created
1655083181083 Thread-2 has been created
1655083181083 开始 下发任务:1 当前线程总数:2
1655083181084 完成 下发任务:1 当前线程总数:2 队列中的线程数量:1
1655083181085 MyTask [name=1] 开始运行! 运行线程 Thread-2 需要(秒):1000
1655083181085 子线程 Thread-0【正在】监控主进程 Thread-2 任务1
1655083181086 MyTask [name=2] 开始运行! 运行线程 Thread-1 需要(秒):4000
1655083181086 开始 下发任务:2 当前线程总数:2
1655083181086 完成 下发任务:2 当前线程总数:2 队列中的线程数量:1
1655083181086 子线程 Thread-1【正在】监控主进程 Thread-1 任务2
1655083181088 开始 下发任务:3 当前线程总数:2
1655083181088 完成 下发任务:3 当前线程总数:2 队列中的线程数量:1
1655083181089 开始 下发任务:4 当前线程总数:2
1655083181089 完成 下发任务:4 当前线程总数:2 队列中的线程数量:2
1655083181091 开始 下发任务:5 当前线程总数:2
1655083181091 完成 下发任务:5 当前线程总数:2 队列中的线程数量:3
1655083181093 MyTask [name=6] 开始运行! 运行线程 Thread-3 需要(秒):12000
1655083181093 Thread-3 has been created
1655083181093 开始 下发任务:6 当前线程总数:2
1655083181093 完成 下发任务:6 当前线程总数:3 队列中的线程数量:3
1655083181093 子线程 Thread-2【正在】监控主进程 Thread-3 任务6
1655083181095 MyTask [name=7] 开始运行! 运行线程 Thread-4 需要(秒):1000
1655083181095 Thread-4 has been created
1655083181095 开始 下发任务:7 当前线程总数:3
1655083181095 完成 下发任务:7 当前线程总数:4 队列中的线程数量:3
1655083181095 子线程 Thread-3【正在】监控主进程 Thread-4 任务7
1655083181097 MyTask [name=8] 开始运行! 运行线程 Thread-5 需要(秒):16000
1655083181097 Thread-5 has been created
1655083181097 开始 下发任务:8 当前线程总数:4
1655083181097 完成 下发任务:8 当前线程总数:5 队列中的线程数量:3
1655083181097 子线程 Thread-4【正在】监控主进程 Thread-5 任务8
1655083181099 MyTask [name=9] rejected from java.util.concurrent.ThreadPoolExecutor@4b1210ee[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
1655083181099 开始 下发任务:9 当前线程总数:5
1655083181099 完成 下发任务:9 当前线程总数:5 队列中的线程数量:3
1655083181101 MyTask [name=10] rejected from java.util.concurrent.ThreadPoolExecutor@4b1210ee[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
1655083181101 开始 下发任务:10 当前线程总数:5
1655083181101 完成 下发任务:10 当前线程总数:5 队列中的线程数量:3
1655083182085 MyTask [name=1] 运行结束! 运行线程 Thread-2
1655083182085 MyTask [name=3] 开始运行! 运行线程 Thread-2 需要(秒):1000
1655083182085 子线程 Thread-5【正在】监控主进程 Thread-2 任务3
1655083182095 MyTask [name=4] 开始运行! 运行线程 Thread-4 需要(秒):8000
1655083182095 MyTask [name=7] 运行结束! 运行线程 Thread-4
1655083182095 子线程 Thread-6【正在】监控主进程 Thread-4 任务4
1655083183090 MyTask [name=3] 运行结束! 运行线程 Thread-2
1655083183090 MyTask [name=5] 开始运行! 运行线程 Thread-2 需要(秒):1000
1655083183090 子线程 Thread-7【正在】监控主进程 Thread-2 任务5
1655083184100 MyTask [name=5] 运行结束! 运行线程 Thread-2
1655083185087 MyTask [name=2] 运行结束! 运行线程 Thread-1
1655083186085 子线程 Thread-0【完成】监控主进程 Thread-2 任务1
1655083186086 子线程 Thread-1【完成】监控主进程 Thread-1 任务2
1655083186094 MyTask [name=6] 被打断 运行线程 Thread-3
1655083186094 子线程 Thread-2【杀掉】主进程(超时了) Thread-3 任务6
1655083186094 子线程 Thread-2【完成】监控主进程 Thread-3 任务6
1655083186096 子线程 Thread-3【完成】监控主进程 Thread-4 任务7
1655083186098 MyTask [name=8] 被打断 运行线程 Thread-5
1655083186098 子线程 Thread-4【杀掉】主进程(超时了) Thread-5 任务8
1655083186098 子线程 Thread-4【完成】监控主进程 Thread-5 任务8
1655083187087 子线程 Thread-5【完成】监控主进程 Thread-2 任务3
1655083187103 MyTask [name=4] 被打断 运行线程 Thread-4
1655083187103 子线程 Thread-6【杀掉】主进程(超时了) Thread-4 任务4
1655083187103 子线程 Thread-6【完成】监控主进程 Thread-4 任务4
1655083188098 子线程 Thread-7【完成】监控主进程 Thread-2 任务5
预启动线程(备战)
预启动线程数(备战):2

ThreadPoolExecutor 线程执行超时,释放线程的更多相关文章

  1. Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行

    Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行 Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执 ...

  2. Java之线程,常用方法,线程同步,死锁

    1, 线程的概念 进程与线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据 ...

  3. Java多线程系列--“基础篇”10之 线程优先级和守护线程

    概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注明出处:http://www.cnblogs.com/skyw ...

  4. Java多线程(十)——线程优先级和守护线程

    一.线程优先级的介绍 java 中的线程优先级的范围是1-10,默认的优先级是5.“高优先级线程”会优先于“低优先级线程”执行. java 中有两种线程:用户线程和守护线程.可以通过isDaemon( ...

  5. Java - 线程优先级和守护线程

    Java多线程系列--“基础篇”10之 线程优先级和守护线程 概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注 ...

  6. java 多线程之 线程优先级和守护线程

    线程优先级的介绍 java 中的线程优先级的范围是1-10,默认的优先级是5."高优先级线程"会优先于"低优先级线程"执行. java 中有两种线程:用户线程和 ...

  7. java 多线程系列基础篇(十)之线程优先级和守护线程

    1. 线程优先级的介绍 java 中的线程优先级的范围是1-10,默认的优先级是5.“高优先级线程”会优先于“低优先级线程”执行. java 中有两种线程:用户线程和守护线程.可以通过isDaemon ...

  8. java多线程与线程并发三:线程同步通信

    本文章内容整理自:张孝祥_Java多线程与并发库高级应用视频教程. 有些时候,线程间需要传递消息,比如下面这道面试题: 子线程循环10次,然后主线程循环100次,然后又回到子线程循环50次,然后再回到 ...

  9. python全栈开发,Day41(线程概念,线程的特点,进程和线程的关系,线程和python理论知识,线程的创建)

    昨日内容回顾 队列 队列:先进先出.数据进程安全 队列实现方式:管道+锁 生产者消费者模型:解决数据供需不平衡 管道 双向通信,数据进程不安全 EOFError: 管道是由操作系统进行引用计数的 必须 ...

  10. Java 多线程基础(十一)线程优先级和守护线程

    Java 多线程基础(十一)线程优先级和守护线程 一.线程优先级 Java 提供了一个线程调度器来监控程序启动后进去就绪状态的所有线程.线程调度器通过线程的优先级来决定调度哪些线程执行.一般来说,Ja ...

随机推荐

  1. Kubernetes:kube-apiserver 之启动流程(二)

    接着 Kubernetes:kube-apiserver 之启动流程(一) 加以介绍. 1.2.2 创建 APIExtensions Server 创建完通用 APIServer 后继续创建 APIE ...

  2. .NET8 WebApplication剖析

    ​ WebApplication 是用于配置HTTP管道和路由的web应用程序,接来下我将一一拆解它的组成. /// <summary> /// The web application u ...

  3. [Jetson Nano]SSH连接Jetson Nano时出现Xlib: extension NV-GLX missing on display localhost:10.0

    解决SSH连接Jetson Nano时遇到的"Xlib: extension "NV-GLX" missing on display 'localhost:10.0'&q ...

  4. CF1592C. Bakry and Partitioning

    原题链接:CF1592C. Bakry and Partitioning 题意: 给定一个\(n\)个点,\(n - 1\)条边的树,并且每个点都有权值\(w_i\),让你最少割掉一条边最多割掉\(k ...

  5. Postgresql——jsonb类型

    Postgresql Json 最近有个功能,需要用到 NoSQL 数据库.但是又不想因为这个小小的功能给系统增加一个 MongoDB 数据库,于是就想到了 Postgresql 支持 JSON 类型 ...

  6. 实现金蝶云星空与赛意SMOM系统的无缝数据对接

    1. 金蝶云星空:为运营协同与管控型企业提供通用ERP服务平台 金蝶云星空是基于当今先进管理理论和数十万家国内客户最佳应用实践开发的ERP服务平台.它针对事业部制.多地点.多工厂等企业和集团公司,提供 ...

  7. 旺店通·企业奇门和用友BIP接口打通对接实战

    旺店通·企业奇门和用友BIP接口打通对接实战 接通系统:旺店通·企业奇门 旺店通是北京掌上先机网络科技有限公司旗下品牌,国内的零售云服务提供商,基于云计算SaaS服务模式,以体系化解决方案,助力零售企 ...

  8. .net中优秀依赖注入框架Autofac看一篇就够了

    Autofac 是一个功能丰富的 .NET 依赖注入容器,用于管理对象的生命周期.解决依赖关系以及进行属性注入.本文将详细讲解 Autofac 的使用方法,包括多种不同的注册方式,属性注入,以及如何使 ...

  9. Go笔记(4)-流程控制

    5.Go语言流程控制 程序流程的控制结构一般有三种,顺序结构,选择结构,循环结构 (1)选择结构 if语句 if流程控制与其他语言的if流程控制基本相同 package main import &qu ...

  10. 吉特日化MES系统&各类化妆品检验标准汇总

    在日化行业中,生产配料过程中,对产品的检验主要分为四大类: (1) 感官指标 (2) 理化指标 (3) 微生物指标 (4) 毒理指标 根据每个产品的不同,其指标会有所不同