Java中的多线程:字段未按预期递增
我很难创建一个实例并使其在所有线程之间共享,下面是我的代码: 以下是主要方法:Java中的多线程:字段未按预期递增,java,multithreading,thread-safety,synchronized,Java,Multithreading,Thread Safety,Synchronized,我很难创建一个实例并使其在所有线程之间共享,下面是我的代码: 以下是主要方法: public static void main(String... args) throws IOException, ClassNotFoundException { MainApp mainApp = new MainApp(); mainApp.init(); mainApp.multiThread(); } 这是init(): 总连接数为100,每条线
public static void main(String... args) throws IOException, ClassNotFoundException {
MainApp mainApp = new MainApp();
mainApp.init();
mainApp.multiThread();
}
这是init():
总连接数
为100,每条线路
为100
下面是多线程()
下面是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)
公共布尔检查(){
试一试{
executor=Executors.newFixedThreadPool(线程计数);
completionService=新的执行者completionService(执行者);
提交(任务计数);
破坏();
System.out.println(“检查完成->确定!!!”;
}捕获(例外e){
System.out.println(“进程-{}”+e时的异常);
}
返回true;
}
私有void submit(int taskCount)引发InterruptedException、ExecutionException{
对于(int i=0;i=taskCount)中断;
}
System.out.println(“---\naverageLatencyOfAllAverages=“+averageLatencyOfAllAverages/taskCount+”毫秒\nminLatencyOfAllMins=“+minLatencyOfAllMins
+“ms\nmaxLatencyOfAllMaxs=“+maxLatencyOfAllMaxs+”ms”);
System.out.println(“总请求数:“+totalInfo.getTotal()+”,总高于阈值:“+totalInfo.GetOverThreshold()+”,比率(高于阈值/总计):“+(totalInfo.GetOverThreshold()/totalInfo.getTotal());
System.out.println(“所有任务都已完成”);
}
私有空间销毁(){
if(this.executor!=null&&!executor.isshutton()){
System.out.println(“关闭并等待所有工作线程终止”);
此为.executor.shutdownow();
而(!this.executor.isTerminated()){
试一试{
睡眠(1000);
}捕捉(中断异常e){
System.out.println(“发生中断异常:{}”+e.getMessage());
}
System.out.println(“关机->确定!!!”;
}
}
}
下面是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;
}
}
公共类MaterializationCallable实现可调用{
公共静态最终整数持续时间=30;
私人最终TotalInfo TotalInfo;
@Getter私有列表延迟;
公共物化可调用(TotalInfo TotalInfo){
this.latencies=new ArrayList();
this.totalInfo=totalInfo;
}
@凌驾
公共MaterializationCallable调用()引发异常{
长期总趋势=0;
long maxLatency=long.MIN_值;
long minLatency=long.MAX_值;
totalInfo.increaseTotal();
对于(int i=0;ioneLatency){
minLatency=oneLatency;
}
if(maxLatency阈值){
totalInfo.IncreaseUpperThreshold();
System.out.println(“[]此请求超过阈值:“+threshold+”毫秒,并用“+oneLatency+”毫秒完成,其端点=”+endpoint);
}
}
}
延迟。添加(平均值);
延迟。添加(最小延迟);
添加(最大延迟);
System.out.println(“Thread”+Thread.currentThread().getId()+“完成”);
归还这个;
}
}
我的问题是:
在materializationChecker.check()
方法的末尾,totalInfo.getTotal()
只是100
而不是1000
,我已经初始化了10个线程池,并提交了100次任务,为什么totalInfo
对象字段没有增加1000次
出了什么问题?
请帮助我理解这一点
非常感谢 那是因为您只提交了
100个任务
您的代码旨在为提交的每个任务将TotalInfo
值增加1。执行器有10个
线程这一事实与TotalInfo
的值的计算方式无关
10
线程只允许执行者执行10
并发任务,仅此而已。这是因为您只提交了100
任务
您的代码旨在为提交的每个任务将TotalInfo
值增加1。执行器有10个
线程这一事实与TotalInfo
的值的计算方式无关
10
线程只允许执行器执行10
并发任务
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++;
}
}
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 !!!");
}
}
}
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;
}
}