我正在做这个练习:
生成1000个线程,每个线程递增一个计数器100,000次。比较使用AtomicLong和LongAdder的性能。
以下是我的执行情况:
import java.io.*;
import java.util.*;
import java.nio.file.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class AtomicLongVsLongAddr {
// 9. Generate 1,000 threads, each of which increments a counter
// 100,000 times. Compare the performance of using AtomicLong
// versus LongAdder.
AtomicLong al = new AtomicLong(0);
LongAdder la = new LongAdder();
public class AtomicLongThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100000; i ++) {
al.incrementAndGet();
}
}
}
public class LongAdderThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100000; i ++) {
la.increment();
}
}
}
public static void main(String[] args) {
AtomicLongVsLongAddr vs = new AtomicLongVsLongAddr();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
(vs.new AtomicLongThread()).start();
}
long endTime = System.currentTimeMillis();
System.out.printf("AtomicLong--Number: %s, Time: %d\n", vs.al, endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
(vs.new LongAdderThread()).start();
}
long res = vs.la.sum();
endTime = System.currentTimeMillis();
System.out.printf("LongAdder--Number: %s, Time: %d\n", res, endTime - startTime);
}
}每次运行这个程序时,我都会得到类似于标准输出的如下内容:
AtomicLong--Number: 100000000, Time: 2330
LongAdder--Number: 99882179, Time: 469显然,我在LongAdder中得到了一个错误的值,但是我不知道我在哪里做错了。
你能帮帮我吗?
已更新
在在座各位和@Ravindra Ranwala的帮助下,我更新了上述练习的答案:
import java.io.*;
import java.util.*;
import java.nio.file.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class AtomicLongVsLongAddr {
// 9. Generate 1,000 threads, each of which increments a counter
// 100,000 times. Compare the performance of using AtomicLong
// versus LongAdder.
AtomicLong al = new AtomicLong(0);
LongAdder la = new LongAdder();
public class AtomicLongThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100000; i ++) {
al.incrementAndGet();
}
}
}
public class LongAdderThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100000; i ++) {
la.increment();
}
}
}
public static void main(String[] args) {
try{
long startTime;
long endTime;
AtomicLongVsLongAddr vs = new AtomicLongVsLongAddr();
Thread[] t = new Thread[1000];
for (int i = 0; i < 1000; i ++) {
t[i] = vs.new AtomicLongThread();
}
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
t[i].start();
t[i].join();
}
endTime = System.currentTimeMillis();
System.out.printf("AtomicLong--Number: %s, Time: %d\n", vs.al, endTime - startTime);
for (int i = 0; i < 1000; i ++) {
t[i] = vs.new LongAdderThread();
}
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i ++) {
t[i].start();
t[i].join();
}
long res = vs.la.sum();
endTime = System.currentTimeMillis();
System.out.printf("LongAdder--Number: %s, Time: %d\n", res, endTime - startTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}如果还有什么不对的地方,请帮我指出。谢谢大家。
发布于 2018-06-26 11:42:55
调用所有线程上的Thread.join并等待所有线程完成。您的主线程似乎在其他增加两个变量完成的线程之前退出。你在这里得到的是一些中间的结果。
这是密码,
public static void main(String[] args) throws InterruptedException {
final List<Thread> adderThreads = new ArrayList<>();
final List<Thread> atomicThreads = new ArrayList<>();
AtomicLongVsLongAddr vs = new AtomicLongVsLongAddr();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
final AtomicLongThread atomicThread = vs.new AtomicLongThread();
atomicThreads.add(atomicThread);
atomicThread.start();
}
for (Thread thread : atomicThreads) {
thread.join();
}
long endTime = System.currentTimeMillis();
System.out.printf("AtomicLong--Number: %s, Time: %d\n", vs.al, endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
final LongAdderThread adderThread = vs.new LongAdderThread();
adderThreads.add(adderThread);
adderThread.start();
}
for (Thread thread : adderThreads) {
thread.join();
}
long res = vs.la.sum();
endTime = System.currentTimeMillis();
System.out.printf("LongAdder--Number: %s, Time: %d\n", res, endTime - startTime);
}发布于 2018-06-26 11:45:45
您的代码不是同步的--主线程在完成计数器线程之前将退出/继续,从而造成差异。
https://stackoverflow.com/questions/51041966
复制相似问题