我想在某個時候使用snmp方法通過多執行緒查詢一些資料,如果超過時間,那么任務將被取消,我這樣寫代碼,如果我的代碼有問題(這意味著執行緒可能只做第 1 步和第 2 步,但不要執行第 4 步:關閉 snmp 連接),如何解決?我可以使用取消任務的方法,我仍然可以在第 4 步關閉 snmp 客戶端嗎?
public static void main(String[] args) throws InterruptedException {
var pool = new ThreadPoolExecutor(
100, 100, 0L, TimeUnit.NANOSECONDS, new LinkedBlockingQueue<>(100));
System.out.println("Executing first batch of tasks...");
submitTasks(pool);
System.out.println("Finish first batch of tasks...");
//call submitTasks(pool) many times
...
}
private static void submitTasks(ExecutorService executor) throws InterruptedException {
var tasks = new ArrayList<Callable<String>>(100);
for (int i = 0; i < 100; i ) {
tasks.add(() -> {
try {
//1.create snmp client
//2.query data with udp link
//3.return result
return result;
}catch (Exception ex){
log.error(String.valueOf(ex));
}
} finally {
//4.close snmp
if (snmp != null) {
snmp.close();
}
}
});
}
List<Future<String>> futureList=executor.invokeAll(tasks,1,TimeUnit.SECONDS);
List<String> list=new ArrayList<>();
for (int i = 0; i < futureList.size(); i ) {
Future<String> future = futureList.get(i);
try {
list.add(future.get());
} catch (CancellationException e) {
log.info("timeOut Task:{}", i);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
我已經從 Alexander Pavlov 的示例中更改了代碼,似乎如果任務被取消,finally 代碼將永遠不會運行。
public static void main(String[] args) throws InterruptedException {
var pool = new ThreadPoolExecutor(
3, 3, 0L, TimeUnit.NANOSECONDS, new LinkedBlockingQueue<>(1));
try {
System.out.println("Executing first batch of tasks...");
submitTasks(pool);
System.out.println("Executing second batch of tasks...");
} finally {
pool.shutdown();
}
}
private static void submitTasks(ExecutorService executor) throws InterruptedException {
var tasks = new ArrayList<Callable<String>>(3);
final var latch = new CountDownLatch(3);
log.info(String.valueOf(latch.getCount()));
for (int i = 0; i < 3; i ) {
tasks.add(() -> {
try {
String s="1";
log.info("this.name:" Thread.currentThread().getName());
for(int a=0;a<1000000L;a ) {
s=a "";
}
return s;
}catch (Exception ex){
log.error(String.valueOf(ex));
}finally {
latch.countDown();
}
return null;
});
}
List<Future<String>> futureList=executor.invokeAll(tasks,1,TimeUnit.NANOSECONDS);
List<String> list=new ArrayList<>();
//latch.await();//
for (int i = 0; i < futureList.size(); i ) {
Future<String> future = futureList.get(i);
try {
list.add(future.get());
} catch (CancellationException e) {
log.info("timeOut Task:{}", i);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
log.info(String.valueOf(latch.getCount()));
log.info("start to await:");
try {
latch.await(); // WAIT UNTIL ALL TASKS ARE REALLY DONE
} catch (InterruptedException ex) {
log.error(String.valueOf(ex));
}
//never log end to await
log.info("end to await:");
log.info(String.valueOf(latch.getCount()));
}
uj5u.com熱心網友回復:
invokeAll超時只是呼叫Thread.interrupt()正在運行的任務。它不會等到任務停止,它會通知任務請求中斷。此外,某些任務可能會忽略中斷并繼續作業。因此,當您從那里回傳時submitTasks,并不意味著所有底層任務都真正停止了。
如果您想 100% 確保在退出時所有任務都停止,submitTasks則使用CountDownLatch來控制真正完成的任務數量,并在運行任務計數為零時退出。
private static void submitTasks(ExecutorService executor) throws InterruptedException {
var c = 100;
final var latch = new CountDownLatch(c); // EXPECT 100 TASKS TO BE COMPLETED
var tasks = new ArrayList<Callable<String>>(c);
for (int i = 0; i < c; i ) {
tasks.add(() -> {
try {
//1.create snmp client
//2.query data with udp link
//3.return result
return result;
} catch (Exception ex) {
log.error(String.valueOf(ex));
} finally {
//4.close snmp
if (snmp != null) {
snmp.close();
}
latch.countDown(); // 1 MORE TASK IS COMPLETED
}
});
}
List<Future<String>> futureList = executor.invokeAll(tasks, 1, TimeUnit.SECONDS);
List<String> list = new ArrayList<>();
for (int i = 0; i < futureList.size(); i ) {
Future<String> future = futureList.get(i);
try {
list.add(future.get());
} catch (CancellationException e) {
log.info("timeOut Task:{}", i);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
try {
latch.await(); // WAIT UNTIL ALL TASKS ARE REALLY DONE
} catch (InterruptedException ex) {
log.error(ex);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/496642.html
