我正在做这个练习:
生成1,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();
}
}
}
如果仍然有任何错误,请为我指出。谢谢大家。
答案 0 :(得分:6)
在所有线程上调用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);
}
答案 1 :(得分:1)
您的代码不是同步的-主线程将在完成计数器线程之前退出/继续,从而产生差异。