在Java中,i++和++i都是xian线程不安全的,如果要用十个线程累加一个资源,就会出现错误。synchronized和Atomic是实现线程安全常用方法。而二者效率问题孰优孰劣?
本着规律符合任意情况原则,简单写了一个测试代码:
public class AtomicTest {
int count = 0;
AtomicInteger count1 = new AtomicInteger(0);//2283 1895 2328 2015 2264
//57 56 55
synchronized void m() {
for (int i = 0; i < 150000; i++) {
count++;
}
}
void n() {
for (int i = 0; i < 150000; i++) {
count1.incrementAndGet();
}
}
public static void main(String a[]) {
long start = System.currentTimeMillis();
AtomicTest t = new AtomicTest();
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 10; i++) {
threads.add(new Thread(t::m, "thread " + i));
}
threads.forEach((o) -> o.start());
threads.forEach((o) -> {
try {
o.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("increase-->" + t.count);
System.out.println(System.currentTimeMillis() - start);
System.out.println("----------------------------------");
long start1 = System.currentTimeMillis();
AtomicTest t1 = new AtomicTest();
List<Thread> thread = new ArrayList<>();
for (int i = 0; i < 10; i++) {
thread.add(new Thread(t1::n, "thread " + i));
}
thread.forEach((o) -> o.start());
thread.forEach((o) -> {
try {
o.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("atomic-->" + t1.count1);
System.out.println(System.currentTimeMillis() - start1);
}
}
测试过后发现,并非Atomic方法一定由于synchronized
当低并发时(小于150000),Atomic效率优于synchronized
当高并发时(大于150000),synchronized效率优于Atomic
*150000为本机测试数据,不准
总结:
synchronized :重量级操作,基于悲观锁,可重入锁。
AtomicInteger:乐观 ,用CAS实现
当并发量大时,Atomic 出错概率会增大,不断校正错误更费时间
原文链接:https://blog.csdn.net/baidu_35773818/article/details/89604328