[英]Threadpool executor not updating the concurrent hashmap
我使用線程池執行程序生成5個線程,以並行執行5個不同的命令。 在完成每個線程之后,我將使用threadid項作為鍵並以值終止的方式更新並發哈希圖。 但是我的線程池沒有更新成功執行命令的哈希表。
主類:
package com.cisco.executor;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class MainExecutor {
static String element;
static ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<Integer, String>();
static Integer array[] = { 1, 2, 3, 4, 5 };
// static Integer array[] = { 1 };
static List<Integer> threadid = Arrays.asList(array);
static String SQOOP_XXCCS_DS_SAHDR_CORE = ReadProperties.getInstance().getProperty("SQOOP_XXCCS_DS_SAHDR_CORE");
static String SQOOP_XXCCS_DS_CVDPRDLINE_DETAIL = ReadProperties.getInstance()
.getProperty("SQOOP_XXCCS_DS_CVDPRDLINE_DETAIL");
static String SQOOP_XXCCS_DS_INSTANCE_DETAIL = ReadProperties.getInstance()
.getProperty("SQOOP_XXCCS_DS_INSTANCE_DETAIL");
static String SQOOP_XXCCS_SCDC_PRODUCT_PROFILE = ReadProperties.getInstance()
.getProperty("SQOOP_XXCCS_SCDC_PRODUCT_PROFILE");
static String SQOOP_MTL_SYSTEM_ITEMS_B = ReadProperties.getInstance().getProperty("SQOOP_MTL_SYSTEM_ITEMS_B");
public static void main(String[] args) {
ThreadPoolExecutor executors = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
// ThreadPoolExecutor executors = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
System.out.println("at executors step");
List<String> getlist = getList();
Iterator<Integer> itr2 = threadid.iterator();
for (Iterator<String> itr = getlist.iterator(); itr.hasNext() && itr2.hasNext();) {
String element = (String) itr.next();
int thread_id = itr2.next();
String[] command = { "ssh", "hddev-c01-edge-02", "\"" + element + "\"" };
System.out.println("the command is as below ");
System.out.println(Arrays.toString(command));
System.out.println("inside the iterator");
ParallelExecutor pe = new ParallelExecutor(command, thread_id, map);
executors.execute(pe);
}
// executors.shutdown();
for(Map.Entry<Integer, String> entry: map.entrySet())
{
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println("The key is " + key + " The value is " + value);
System.out.println("Thread " + key + " is terminated");
}
}
public static List<String> getList() {
List<String> commandlist = new ArrayList<String>();
System.out.println("inside getList");
commandlist.add(SQOOP_XXCCS_DS_SAHDR_CORE);
commandlist.add(SQOOP_XXCCS_DS_CVDPRDLINE_DETAIL);
commandlist.add(SQOOP_XXCCS_DS_INSTANCE_DETAIL);
commandlist.add(SQOOP_XXCCS_SCDC_PRODUCT_PROFILE);
commandlist.add(SQOOP_MTL_SYSTEM_ITEMS_B);
return commandlist;
}
}
可運行類:
package com.cisco.executor;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;
public class ParallelExecutor implements Runnable {
private static Logger LOGGER = Logger.getLogger(ParallelExecutor.class);
String[] command;
int threadid;
ConcurrentHashMap<Integer, String> map;
public ParallelExecutor(String[] command, int threadid, ConcurrentHashMap<Integer, String> map) {
this.command = command;
this.threadid = threadid;
this.map = map;
}
@Override
public void run() {
ProcessBuilder processbuilder = new ProcessBuilder(command);
LOGGER.info(command);
try {
Process process = processbuilder.inheritIO().start();
System.out.println("inside process builder ");
process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String readline;
while ((readline = reader.readLine()) != null) {
LOGGER.info(readline);
}
// getting the thread state and adding it to a collection
Thread.State state = Thread.currentThread().getState();
if (state == Thread.State.TERMINATED) {
map.put(threadid, "TERMINATED");
}
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
}
我的實現是錯誤的。 有人可以幫我實施。
我建議您保留Future對象並檢查它們,而不是嘗試捕獲線程中線程的結果(如果拋出異常/錯誤,則容易出錯)。
ExecutorService exec = Executors.newFixedThreadPool(5);
System.out.println("at executors step");
Map<String, Future<?>> results = new HashMap<>();
for (String element : getList()) {
String[] command = { "ssh", "hddev-c01-edge-02", "\"" + element + "\"" };
results.put(element, exec.submit(new ParallelExecutor(command, thread_id, map)));
}
for(Map.Entry<String, Future<?>> entry: map.entrySet()) {
try {
entry.getValue().get();
System.out.println(entry.getKey()+ " is complete");
} catch (ExecutionException e) {
System.out.println(entry.getKey()+ " failed with");
e.getCause().printStackTrace(System.out);
}
}
ThreadPoolExecutor直到被要求這樣做時才終止。 所以,首先你必須打電話
// executors.shutdown();
,您將其保留為已評論。 2,您需要等待線程正確終止。 為此,在for(Map.Entry entry:map.entrySet())之前添加一個循環
while (!es.isTerminated()) {
}
但是,由於一個線程可能會運行許多可運行對象,並且如果我正確理解了您的信息,那么一旦執行了一個可運行對象,您就想更新CHM。
為此,您必須使用CustomThread類。 擴展線程並僅覆蓋afterExecute()
方法中的1個方法,您需要在其中放置代碼以使用Runnable的ID和終止狀態更新CHM。 但是請記住,這意味着完成傳遞的Runnables run()方法,而不是基礎線程的終止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.