[英]Spring scheduler and Thread pool executor
我在设计基于多线程的应用程序时需要帮助,其中包括动态URL创建及其通过线程的处理。
我在应用程序中使用spring调度程序,该调度程序每30秒调度一次。 从该计划方法中,我正在调用一些基于服务的API,这些API处于循环中,并且每个API需要1个线程池执行程序以及1个线程处理能力。
由于此过程是通过计划的方法进行的,因此每次创建新的线程池时,这就是问题所在。 您可以在代码中看到。
我想要的是,如果对于任何一种API,如果线程池已经存在,则该线程应该能够通过不创建新的线程池并开始处理来自己识别。
让我知道,如果需要更多信息。
任何建议都值得欢迎和赞赏。 谢谢
#API Properties
service.url=http://{0}.abc.net/xyz.php?
service.urls = abc1, abc2, abc3, abc4, abc5
@Service
public class APIServiceImpl implements APIService {
@Autowired
MsgService msgService;
private static final Logger LOGGER = Logger.getLogger(APIServiceImpl.class);
private static Properties fileProperties = PropertyUtility.getfileProperties();
@Scheduled(fixedDelayString = "30000")
public void getServiceMessage() throws ServiceException {
try {
long startTime = System.currentTimeMillis() / 1000L;
long endTime = startTime + 30;
String urlStr = fileProperties.getProperty("service.urls");
String[] urls = urlStr.split(",");
foreach(String url : urls){
serviceApi(url.trim(), startTime, endTime);
}
} catch (Exception e) {
throw new ServiceException(e);
}
}
private void serviceApi(String url, long startTime, long endTime) {
StringBuffer buffer = new StringBuffer();
buffer.append(java.text.MessageFormat.format(fileProperties.getProperty("service.url"), url));
buffer.append("starttime=" + startTime);
buffer.append("&endtime=" + endTime);
ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(100), new ThreadPoolExecutor.CallerRunsPolicy());
executor.submit(new APIThreadHandler(buffer.toString(), messageService));
}
public class APIThreadHandler implements Runnable {
private static final Logger LOGGER = Logger.getLogger(APIThreadHandler.class);
private String url;
MsgService msgService;
public APIThreadHandler(String url, MsgService msgService) {
this.url = url;
this.msgService = msgService;
}
public void run() {
System.out.println("ThreadID: " + Thread.currentThread().getId());
try {
URL srcUrl = new URL(url);
List<Map<?, ?>> data = readObjectsFromCsv(srcUrl);
JSONArray jsonArray = new JSONArray(data);
for (int i = 0; i < jsonArray.length(); i++) {
msgService.sendMessage(jsonArray.getJSONObject(i));
}
} catch (Exception e) {
LOGGER.error("Exception occured - ", e);
}
}
private static List<Map<?, ?>> readObjectsFromCsv(URL url) {
List<Map<?, ?>> listMap = null;
try {
CsvSchema bootstrap = CsvSchema.emptySchema().withHeader();
CsvMapper csvMapper = new CsvMapper();
MappingIterator<Map<?, ?>> mappingIterator = csvMapper.readerFor(Map.class).with(bootstrap).readValues(url);
listMap = mappingIterator.readAll();
} catch (Exception e) {
LOGGER.error("Exception occured - ", e);
}
return listMap;
}
您可以使用@ PostConstruct一次初始化线程池,然后每次重复使用该线程池。 当应用程序上下文被加载时,将仅调用一次。
@PostConstruct
public void init() {
executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(100), new ThreadPoolExecutor.CallerRunsPolicy());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.