问题:比如多线程进行io操作的时候,io的读取在等待的时候(比如telnet某端口时,会长时间等待),线程是不会关闭的,这样导致线程不释放,早晚凉凉。
线程池关闭线程的方式有很多,我使用以下两种,简单介绍下,希望能帮助到你。
1、编写守护线程,来关闭你的当前线程
思路:创建守护线程执行业务操作,编写用户线程超时退出,当用户线程退出后,守护线程将强制退出。代码如下:
package BK2020.M08.D27;
/**
* @description:
* @Author: huangsan
* @Date: 2020/8/28 9:34 下午
*/
public class TimeOutThread extends Thread {
@Override
public void run() {
try {
Thread.sleep(3000);
System.out.println("超时结束了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
DeamonThread t1 = new DeamonThread();
TimeOutThread t2 = new TimeOutThread();
t1.setDaemon(true);
t1.start();
t2.start();
}
}
package BK2020.M08.D27;
/**
* @description:
* @Author: huangsan
* @Date: 2020/8/28 9:30 下午
*/
public class DeamonThread extends Thread {
@Override
public void run() {
while (true) {
try {
Thread.sleep(99999999);//模拟IO等待
} catch (InterruptedException e) {
System.out.println("强制中断");
}
break;
}
}
}
2、使用future来实现
思路:通过future的get超时方法,超时的部分直接废弃掉,调用shutdownNow关闭其他线程,针对线程做异常处理
通过查看shutdown与shutdownNow我们可以知道,shutdown是会将等待状态下线程继续执行不会关闭的,解决不了我们的问题,所以使用shutdownNow强制关闭,但是这样的话我们的线程就会抛出异常,做好异常的处理即可。代码如下:
package BK2020.M08.D27;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
/**
* @description:
* @Author: huangsan
* @Date: 2020/8/28 8:49 下午
*/
public class ThreadPoolCloseDemo {
public static void main(String[] args) {
allDeviceStatusMonitor();
}
public static void allDeviceStatusMonitor() {
ThreadPoolExecutor myExecutor = new ThreadPoolExecutor(
32,
64,
20,
TimeUnit.SECONDS,
new SynchronousQueue<>());
List<String> onlineIp = new ArrayList<>();
List<String> ips = Arrays.asList("10.0.30.50", "10.0.30.51");
List<Future> futureList = new ArrayList<>();
for (String ip : ips) {
//应用telnet
Future<String> submit = myExecutor.submit(
() -> {
if (doTelnet(ip, "8080")) {
return ip;
}
return "xxx";
});
futureList.add(submit);
}
for (Future<String> future : futureList) {
try {
//超时后将放弃该状态,默认为离线
String ip = future.get(2, TimeUnit.SECONDS);
onlineIp.add(ip);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("超时放弃");
}
}
//尝试关闭线程池,如果后续还有等待线程调用shutdownnow
myExecutor.shutdown();
try {
if (!myExecutor.awaitTermination(2, TimeUnit.SECONDS)) {
myExecutor.shutdownNow();
}
} catch (InterruptedException e) {
myExecutor.shutdownNow();
}
System.out.println("全体在线设备及系统:" + onlineIp);
}
private static boolean doTelnet(String telnetIp, String telnetPort) {
if ("10.0.30.50".equals(telnetIp)) {
return true;
}
while (true) {
try {
Thread.sleep(99999999);//模拟IO等待
} catch (InterruptedException e) {
System.out.println("强制中断");
}
return false;
}
}
}