概述
对于这两种锁,在jdk1.6之前synchronized的性能是远不如Lock的,因为synchronized需要调用操作系统的函数,操作内核来完成,比较费时,在JDK1.6以后Oracle公司对synchronized进行了大量优化,引入了偏向锁,自旋锁等jvm级别的锁机制,从而让性能得到了大大的跃升,在普遍使用JDK1.8的现在,出于好奇,我简单测试了下synchronized和Lock在JDK1.8下两者间的性能。
单线程下,使用synchronized和Lock分别进行100次0到100万的叠加操作,此时会重复加锁解锁100次,测试代码如下
public class Test2 {
private static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
function1();
}
System.out.println("单线程,synchronized耗时:" + (System.currentTimeMillis() - start));
/*long start2 = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
function2();
}
System.out.println("单线程,Lock耗时:" + (System.currentTimeMillis() - start2));*/
}
/**
* 使用synchronized进行1-100万的叠加
*/
public synchronized static void function1() {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
}
/**
* 使用Lock进行1-100万的叠加
*/
public static void function2() {
lock.lock();
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
lock.unlock();
}
}
结果(各取3次结果):
单线程,synchronized耗时:6
单线程,synchronized耗时:5
单线程,synchronized耗时:5
单线程,Lock耗时:35
单线程,Lock耗时:35
单线程,Lock耗时:35
可以看到在单线程情况下,synchronized的性能优于Lock,synchronized的加锁释放锁速度比Lock快;
10个线程下,分别使用synchronized和lock进行了100次0到100万的叠加操作,会竞争锁10次,测试代码如下:
/*----------------------------------------------------*/
/*-------------------- 测试类 -------------------------*/
/*----------------------------------------------------*/
public class Test {
//线程数量
private static int threadCounts = 10;
//用于让线程同时运行,使得数据更加精确
public static CountDownLatch latch = new CountDownLatch(threadCounts);
//用于让计算的时间更加精确
public static CyclicBarrier cyc = new CyclicBarrier(threadCounts + 1);
public static void main(String[] args) {
List<Thread> threads1 = new ArrayList<>();
for (int i = 0; i < threadCounts; i++) {
Thread thread = new Thread(new SyncTest());
threads1.add(thread);
thread.start();
latch.countDown();
}
long start = System.currentTimeMillis();
try {
Test.cyc.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(threadCounts+"个线程,synchronized耗时:"+(System.currentTimeMillis()-start));
/*--------------------- 测试lock,分开测试,让数据更准确 --------------------------*/
/*Lock lock = new ReentrantLock();
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < threadCounts; i++) {
Thread thread = new Thread(new LockTest(lock));
threads.add(thread);
thread.start();
latch.countDown();
}
long start2 = System.currentTimeMillis();
try {
Test.cyc.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(threadCounts + "个线程,lock耗时:" + (System.currentTimeMillis() - start2));*/
}
}
/**
* synchronized的Runnable类
*/
class SyncTest implements Runnable {
@Override
public void run(){
try {
Test.latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (SyncTest.class) {
for (int i = 0; i < 100; i++) {
function();
}
Test.i++;
}
try {
Test.cyc.await();
} catch (Exception e) {
e.printStackTrace();
}
}
public void function() {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
}
}
/**
* Lock的Runnable类
*/
class LockTest implements Runnable {
private Lock lock;
public LockTest(Lock lock) {
this.lock = lock;
}
@Override
public void run() {
try {
Test.latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.lock();
for (int i = 0; i < 100; i++) {
function();
}
lock.unlock();
try {
Test.cyc.await();
} catch (Exception e) {
e.printStackTrace();
}
}
public void function() {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
}
}
结果(各取3次结果):
10个线程,synchronized耗时:5
10个线程,synchronized耗时:5
10个线程,synchronized耗时:5
10个线程,lock耗时:5
10个线程,lock耗时:5
10个线程,lock耗时:5
和上面同样的代码逻辑,我将线程数调到1000,得到如下结果(各取3次结果):
1000个线程,synchronized耗时:72
1000个线程,synchronized耗时:60
1000个线程,synchronized耗时:67
1000个线程,lock耗时:82
1000个线程,lock耗时:85
1000个线程,lock耗时:83
最后,我将线程数量调整到1万,得到如下结果(各取3次结果):
10000个线程,synchronized耗时:6613
10000个线程,synchronized耗时:7619
10000个线程,synchronized耗时:7063
10000个线程,lock耗时:7310
10000个线程,lock耗时:7257
10000个线程,lock耗时:7905
这次测试比较简单,但也基本能看出jdk1.8版本中,1万个并发以内synchronized和Lock的性能并没有太大的区别,这些测试数据仅仅是我使用个人笔记本测试所得,仅能当一个简单参考。
最后
以上就是痴情蓝天为你收集整理的一次对于synchronized和Lock两种锁的性能测试和比较的全部内容,希望文章能够帮你解决一次对于synchronized和Lock两种锁的性能测试和比较所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复