我无法创建一个实例并让它在所有线程之间共享,这是我的代码:
这是主要方法:
public static void main(String... args) throws IOException, ClassNotFoundException {
MainApp mainApp = new MainApp();
mainApp.init();
mainApp.multiThread();
}
这是init():
private void init() {
HttpClient httpClient = HttpClientBuilder.create()
.setMaxConnTotal(TOTAL_CONNECTION)
.setMaxConnPerRoute(PER_ROUTE)
.build();
final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
restTemplate = new RestTemplate(requestFactory);
}
TOTAL_CONNECTION
为100,PER_ROUTE
为100
这是多线程():
private void multiThread() {
MaterializationChecker materializationChecker = new MaterializationChecker(restTemplate, new TotalInfo(0, 0));
materializationChecker.check();
}
这是TotalInfo类:
public class TotalInfo {
@Getter private int total;
@Getter private int aboveThreshold;
public TotalInfo(int total, int aboveThreshold) {
this.total = total;
this.aboveThreshold = aboveThreshold;
}
protected synchronized void increaseAboveThreshold() {
aboveThreshold++;
}
protected synchronized void increaseTotal() {
total++;
}
}
这是materializationChecker.check()方法:( threadCount
设置为10,taskCount
设置为100)
public boolean check() {
try {
executor = Executors.newFixedThreadPool(threadCount);
completionService = new ExecutorCompletionService<>(executor);
submit(taskCount);
destroy();
System.out.println("Check finished -> OK !!!");
} catch (Exception e) {
System.out.println("exception when process - {}" + e);
}
return true;
}
private void submit(int taskCount) throws InterruptedException, ExecutionException {
for (int i = 0; i < taskCount; i++) {
completionService.submit(new MaterializationCallable(totalInfo));
}
int doneNum = 0;
MaterializationCallable materializationCallable;
Future<MaterializationCallable> future;
long averageLatencyOfAllAverages = 0L, minLatencyOfAllMins = Long.MAX_VALUE, maxLatencyOfAllMaxs = Long.MIN_VALUE;
while ((future = this.completionService.take()) != null) {
materializationCallable = future.get();
doneNum++;
System.out.println("Task " + doneNum + " done.");
averageLatencyOfAllAverages += materializationCallable.getLatencies().get(0);
minLatencyOfAllMins = Math.min(minLatencyOfAllMins, materializationCallable.getLatencies().get(1));
maxLatencyOfAllMaxs = Math.max(maxLatencyOfAllMaxs, materializationCallable.getLatencies().get(2));
if (doneNum >= taskCount) break;
}
System.out.println("----\naverageLatencyOfAllAverages = " + averageLatencyOfAllAverages/taskCount + " miiliseconds\nminLatencyOfAllMins = " + minLatencyOfAllMins
+ " ms\nmaxLatencyOfAllMaxs = " + maxLatencyOfAllMaxs + " ms");
System.out.println("total requests: " + totalInfo.getTotal() + ", total aboveThreshold: " + totalInfo.getAboveThreshold() + ", ratio (aboveThreshold/total): " + (totalInfo.getAboveThreshold()/totalInfo.getTotal()));
System.out.println("all tasks have been done.");
}
private void destroy() {
if (this.executor != null && !executor.isShutdown()) {
System.out.println("Shutdown and wait for all worker threads to be terminated.");
this.executor.shutdownNow();
while (!this.executor.isTerminated()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Occurred InterruptedException : {}" + e.getMessage());
}
System.out.println("Shutdown -> OK !!!");
}
}
}
这是MaterializationCallable类的代码:
public class MaterializationCallable implements Callable<MaterializationCallable> {
public static final int DURATION = 30;
private final TotalInfo totalInfo;
@Getter private List<Long> latencies;
public MaterializationCallable(TotalInfo totalInfo) {
this.latencies = new ArrayList<>();
this.totalInfo = totalInfo;
}
@Override
public MaterializationCallable call() throws Exception {
long totalLatency = 0;
long maxLatency = Long.MIN_VALUE;
long minLatency = Long.MAX_VALUE;
totalInfo.increaseTotal();
for (int i = 0; i < itemIds.size(); i++){
restTemplate.getForObject(endpoint, byte[].class);
if (i != 0) {
long oneLatency = receiveLatency + desiralizeLatency;
totalLatency += oneLatency;
if (minLatency > oneLatency) {
minLatency = oneLatency;
}
if (maxLatency < oneLatency) {
maxLatency = oneLatency;
}
long threshold = TimeUnit.MILLISECONDS.toMillis(DURATION);
if (oneLatency > threshold) {
totalInfo.increaseAboveThreshold();
System.out.println("[] This request went over threshold: " + threshold + " ms, and took " + oneLatency + " ms to finish, its endpoint = " + endpoint);
}
}
}
latencies.add(average);
latencies.add(minLatency);
latencies.add(maxLatency);
System.out.println("Thread " + Thread.currentThread().getId() + " is done.");
return this;
}
}
我的问题是:
在materializationChecker.check()
方法结束时,totalInfo.getTotal()
仅为100
而不是1000
,我已初始化了10个线程池,并提交了100次任务,为什么会来{{ 1}}对象字段不会递增1000次?
出了什么问题? 请帮我理解这一点。
非常感谢!
答案 0 :(得分:2)
那是因为您只提交了100
个任务。
您的代码旨在为每个提交的任务将TotalInfo
值增加一。您的执行程序具有10
个线程的事实与计算TotalInfo
的值的方式无关。
10
个线程只允许执行程序执行10
个并发任务,仅此而已。