【프로젝트 실전】--익명 내부 클래스로 다중 스레드 조작 실현
3948 단어 프로젝트 실전
처음에task-역사 메시지 압축 파일 작업을 수행할 때 익명 내부 클래스를 사용하여 LoopCall 방법을 실현했습니다.여기서 processPageData 메서드에서는 히스토리 메시지를 다중 스레드로 처리합니다.
@Override
public void execute(TaskContext ctx) {
logger.info(" ");
Date minTime = TimeUtil.minusDay(new Date(), keepMaxDay);
LoopPageExecutor.execute(new LoopCall() {
@Override
public List getBatch(int batchSize) {
List batchList = historyDao.queryExistSendTimeEalier(minTime, batchSize);
logger.info(" :" + batchList.size());
return batchList;
}
@Override
public void processPageData(List data) {
List> calls = new LinkedList<>();
for (UserMsgHistory his : data) {
calls.add(new MsgArchiveCall(his, minTime));
}
ConcurrentExecutor.execute(calls, 30);
}
}, 3000);
}
/**
* , 。
* calls , batchSize 。 ,
*
* @param calls
* @param batchSize
* @return
*/
public static List execute(Collection> calls, int batchSize) {
logger.debug(" , :{}", calls.size());
List resultColl = new CopyOnWriteArrayList();
if (CollectionUtils.isEmpty(calls)) {
return resultColl;
}
List>> deviceCalls = CollectionConventer.devide(calls, batchSize);
for (List> batch : deviceCalls) {
List batchResult = execute(batch);
resultColl.addAll(batchResult);
}
return resultColl;
}
/**
* , 。 ,
* , 。
*
* @param calls
*/
public static List execute(Collection> calls) {
logger.debug(" , :{}", calls.size());
List resultColl = new CopyOnWriteArrayList();
if (CollectionUtils.isEmpty(calls)) {
return resultColl;
}
if (calls.size() == 1) {
// ,
ConcurrentCall call = calls.iterator().next();
try {
CountDownLatch cdl = new CountDownLatch(1);
call.setCdl(cdl);
V v = call.call();
resultColl.add(v);
} catch (Exception e) {
e.printStackTrace();
logger.error(" ,{}", e);
// , list
}
return resultColl;
} else {
CountDownLatch cdl = new CountDownLatch(calls.size());
List> futures = new LinkedList<>();
for (ConcurrentCall call : calls) {
call.setCdl(cdl);
Future future = executor.submit(call);
futures.add(future);
}
try {
logger.debug(" ");
cdl.await();
logger.debug(" , ");
for (Future f : futures) {
resultColl.add(f.get());
}
return resultColl;
} catch (InterruptedException | ExecutionException e) {
logger.warn(" ,{}", e);
throw new PushInnerException(e);
}
}
}
/**
* ,
*/
@Data
public static abstract class ConcurrentCall implements Callable {
private CountDownLatch cdl;
@Override
public V call() throws Exception {
try {
V v = this.doCall();
return v;
} catch (Throwable t) {
if (t instanceof PushInnerException) {
logger.error(t.getMessage());
} else {
logger.error("unknown exception", new MailAlarmAppender.MailAlarmException(t));
}
throw new RuntimeException(t);
} finally {
this.cdl.countDown();
}
}
public abstract V doCall() throws Exception;
}
보충:
CopyOnWriteArrayList의 원리와 사용 방법
Java 동시 프로그래밍:Callable, Future 및 FutureTask
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java8 Optional 상세 정보Java8에서는 빈 값에 대한 작업 클래스를 제공합니다.Optional.다음은 그의 방법을 소개한다. 정적 방법: Optional.of (T) 는 Optional 패키지의 대상을 되돌려줍니다. 전송된 파라미터가 비어...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.