java锁消耗的性能,主要是多线程先cpu对线程的调度消耗的,在有锁的情况下,cpu要调度某个线程可用,某个线程不可用,这些本来就是要消耗系统资源的。所以个人认为,多线程下性能下降的原因主要是两方便的,第一 锁消耗性能,第二是线程调度消耗性能。以下通过两个方便为别测试。
?
??? 首先是单线程下,锁消耗的性能:
???????? public class Test {
?? ?private static final int num = 500000000;
?? ?
?? ?public void cal(){
?? ???? long start = System.currentTimeMillis();
?? ???? int result = 0;
?? ????
?? ???? for (int i = 0; i < num; i++) {
?? ???? ??? result +=1;
?? ???? }
?? ???? System.out.println("cal计算结果为: "+result+". 计算的时间为:"+(System.currentTimeMillis()-start));
?? ?}
?? ?
?? ?public? void cal2(){
?? ???? long start = System.currentTimeMillis();
?? ???? int result = 0;
?? ????
?? ???? for (int i = 0; i < num; i++) {
?? ???? ??? synchronized (this) {
?? ???? ??? ??? result +=1;
?? ???? ??? }
?? ???? }
?? ???? System.out.println("cal2有锁计算结果为: "+result+". 计算的时间为:"+(System.currentTimeMillis()-start)+"\r");
?? ?}
?? ?
?? ?public static void main(String[] args) {
?? ????
?? ???? for (int i = 0; i < 10; i++) {
?? ???? ??? Test test = new Test();
?? ???? ???
?? ???? ??? test.cal();
?? ???? ??? test.cal2();
?? ???? }
?? ?}
}
?? 以下是执行结果为了测试的效果,执行10次看平均值:
???? cal计算结果为: 500000000. 计算的时间为:271
cal2有锁计算结果为: 500000000. 计算的时间为:15220
cal计算结果为: 500000000. 计算的时间为:262
cal2有锁计算结果为: 500000000. 计算的时间为:1970
cal计算结果为: 500000000. 计算的时间为:270
cal2有锁计算结果为: 500000000. 计算的时间为:1228
cal计算结果为: 500000000. 计算的时间为:263
cal2有锁计算结果为: 500000000. 计算的时间为:1230
cal计算结果为: 500000000. 计算的时间为:262
cal2有锁计算结果为: 500000000. 计算的时间为:1355
cal计算结果为: 500000000. 计算的时间为:262
cal2有锁计算结果为: 500000000. 计算的时间为:1223
cal计算结果为: 500000000. 计算的时间为:263
cal2有锁计算结果为: 500000000. 计算的时间为:1234
cal计算结果为: 500000000. 计算的时间为:266
cal2有锁计算结果为: 500000000. 计算的时间为:1251
cal计算结果为: 500000000. 计算的时间为:264
cal2有锁计算结果为: 500000000. 计算的时间为:1230
cal计算结果为: 500000000. 计算的时间为:269
cal2有锁计算结果为: 500000000. 计算的时间为:1255
?
?? 从以上的测试结果可以看出有锁的要比无锁的,性能消耗大概在5倍,而且第一次执行的时候相差的都无法让人接受,当然和计算机的配置还是有一定的关系的,但是从这个简单的测试上可以看出,锁对程序的性能影响
?
?? 以下是多线程下,计算的结果,本次测试启用10个线程,每个线程单独计算五亿次
????? public class Test {
??? private static final int num = 500000000;
???
??? public void cal(){
??? ??? long start = System.currentTimeMillis();
??? ??? int result = 0;
??? ???
??? ??? for (int i = 0; i < num; i++) {
??? ??? ??? result +=1;
??? ??? }
??? ??? System.out.println("cal计算结果为: "+result+". 计算的时间为:"+(System.currentTimeMillis()-start));
??? }
???
??? public? void cal2(){
??? ??? long start = System.currentTimeMillis();
??? ??? int result = 0;
??? ???
??? ??? for (int i = 0; i < num; i++) {
??? ??? ??? synchronized (this) {
??? ??? ??? ??? result +=1;
??? ??? ??? }
??? ??? }
??? ??? System.out.println("cal2有锁计算结果为: "+result+". 计算的时间为:"+(System.currentTimeMillis()-start)+"\r");
??? }
???
??? public void cal3(){
??? ??? long start = System.currentTimeMillis();
??? ??? int result = 0;
??? ??? int index = 0;
??? ???
??? ??? while(index<num){
??? ??? ??? synchronized (this) {
??? ??? ??? ??? result+=1;
??? ??? ??? ??? index++;
??? ??? ??? }
??? ??? }
??? ??? System.out.println(Thread.currentThread().getName()+" "+"有锁计算结果为: "+result+". 计算的时间为:"+(System.currentTimeMillis()-start)+"\r");
??? }
???
??? public static void main(String[] args) {
??? ???
??? ??? for (int i = 0; i < 10; i++) {
//??? ??? ??? Test test = new Test();
//??? ??? ???
//??? ??? ??? test.cal();
//??? ??? ??? test.cal2();
??? ??? ??? Thread thread = new Thread(new Runnable() {
??? ??? ??? ???
??? ??? ??? ??? @Override
??? ??? ??? ??? public void run() {
??? ??? ??? ??? ??? Test test = new Test();
??? ??? ??? ??? ??? test.cal3();
??? ??? ??? ??? }
??? ??? ??? }, "线程"+i);
??? ??? ??? thread.start();
??? ??? }
??? }
}
?
?? 接下来看运算结果,表明多线程下的性能下降的更厉害
??? 线程5 有锁计算结果为: 500000000. 计算的时间为:62796
线程7 有锁计算结果为: 500000000. 计算的时间为:62957
线程9 有锁计算结果为: 500000000. 计算的时间为:62961
线程1 有锁计算结果为: 500000000. 计算的时间为:68265
线程2 有锁计算结果为: 500000000. 计算的时间为:85124
线程0 有锁计算结果为: 500000000. 计算的时间为:101602
线程3 有锁计算结果为: 500000000. 计算的时间为:103658
线程6 有锁计算结果为: 500000000. 计算的时间为:116141
线程8 有锁计算结果为: 500000000. 计算的时间为:122378
线程4 有锁计算结果为: 500000000. 计算的时间为:122773