现在的位置: 首页 > 综合 > 正文

volatile,Atomic ,synchronized性能和同步测试程序

2013年07月23日 ⁄ 综合 ⁄ 共 3898字 ⁄ 字号 评论关闭

经常有人提到volatile,Atomic类型,给多线程编程提高性能,自己跑下测试结果就知道了…

import java.util.concurrent.atomic.AtomicInteger;

public class Counter {

	public static int count=0;
	
	public static volatile int volatileCount = 0;
	public static AtomicInteger atomicCount = new AtomicInteger(0);
	
	public static byte[] lock=new byte[0];
	public static int syCount=0;

	
	public static void sleep(final int gap){
		try {
			Thread.sleep(gap);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void incrInt(final int gap){
		count++;
		sleep(gap);
	}
	
	public static void incrVolatileInt(int gap){
		volatileCount++;//和volatileCount上一个状态相关,不具于原子性
		sleep(gap);
	}
	
	public static void incrAtomicInt(final int gap) {
		//第一种方式:
		//int tmp=atomicCount.get();
		//atomicCount.getAndSet(tmp+1);//注意:tmp+1不具原子性
		
		//第二种方式:
		atomicCount.getAndIncrement();//具备原子性的
		sleep(gap);
	}
	
	public static void incrSynInt(final int gap){
		synchronized(lock){
			syCount++;
			sleep(gap);
		}
	}
	
	public static void testInt(int count,final int gap){
		long st=System.currentTimeMillis();
		Thread threads[]=new Thread[count];
		for (int i = 0; i < count; i++) {
		    threads[i]=new Thread(new Runnable() {
		        @Override
		        public void run() {
		        	Counter.incrInt(gap);
		        }
		    });
		    threads[i].start();
		}
		for(int i=0;i<count;i++){
		    try {
		        threads[i].join();
		    } catch (InterruptedException e) {
		        // TODO Auto-generated catch block
		        e.printStackTrace();
		    }
		}
		long et=System.currentTimeMillis();
		System.out.println("---运行时间="+(et-st));
		// 这里每次运行的值都有可能不同,可能为1000
		System.out.println("运行结果:Counter.count=" + Counter.count);
	}
	
	public static void testVolatileInt(int count,final int gap){
		long st=System.currentTimeMillis();
		Thread threads[]=new Thread[count];
		for (int i = 0; i < count; i++) {
		    threads[i]=new Thread(new Runnable() {
		        @Override
		        public void run() {
		        	Counter.incrVolatileInt(gap);
		        }
		    });
		    threads[i].start();
		}
		for(int i=0;i<count;i++){
		    try {
		        threads[i].join();
		    } catch (InterruptedException e) {
		        // TODO Auto-generated catch block
		        e.printStackTrace();
		    }
		}
		long et=System.currentTimeMillis();
		System.out.println("---运行时间="+(et-st));
		System.out.println("运行结果:Counter.volatileCount=" + Counter.volatileCount);
	}
	
	public static void testAtomicInt(int count,final int gap){
		long st=System.currentTimeMillis();
		Thread threads[]=new Thread[count];
		for (int i = 0; i < count; i++) {
		    threads[i]=new Thread(new Runnable() {
		        @Override
		        public void run() {
		            Counter.incrAtomicInt(gap);
		        }
		    });
		    threads[i].start();
		}
		for(int i=0;i<count;i++){
		    try {
		        threads[i].join();
		    } catch (InterruptedException e) {
		        // TODO Auto-generated catch block
		        e.printStackTrace();
		    }
		}
		long et=System.currentTimeMillis();
		System.out.println("---运行时间="+(et-st));
		System.out.println("运行结果:Counter.atomicCount=" + Counter.atomicCount.get());
	}
	
	public static void testSynInt(int count,final int gap){
		long st=System.currentTimeMillis();
		Thread threads[]=new Thread[count];
		for (int i = 0; i < count; i++) {
		    threads[i]=new Thread(new Runnable() {
		        @Override
		        public void run() {
		            Counter.incrSynInt(gap);
		        }
		    });
		    threads[i].start();
		}
		for(int i=0;i<count;i++){
		    try {
		        threads[i].join();
		    } catch (InterruptedException e) {
		        // TODO Auto-generated catch block
		        e.printStackTrace();
		    }
		}
		long et=System.currentTimeMillis();
		System.out.println("---运行时间="+(et-st));
		System.out.println("运行结果:Counter.syCount=" + Counter.syCount);
	}

	public static void main(String[] args) {
		int cnt=100000;
		int gap=2;
		testInt(cnt,gap);
		System.out.println("-------------------------------------------");
		testVolatileInt(cnt,gap);
		System.out.println("-------------------------------------------");
		testAtomicInt(cnt,gap);
		System.out.println("-------------------------------------------");
		testSynInt(cnt,gap);
	}
}

我输出的打印日志:

---运行时间=4655

运行结果:Counter.count=99999

-------------------------------------------

---运行时间=4536

运行结果:Counter.volatileCount=100000

-------------------------------------------

---运行时间=4626

运行结果:Counter.atomicCount=100000

-------------------------------------------

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

at java.lang.Thread.start0(Native Method)

at java.lang.Thread.start(Thread.java:673)

at Counter.testSynInt(Counter.java:136)

at Counter.main(Counter.java:160)

多运行几次会发现结果还时常变化,多线程开发中,如果volatile和volatile之前的值无关才用volatile,因为性能好,不过最好不用,很容易出错的。

Atomic类型最好用它的成员方法,否则请用synchronized来同步。

抱歉!评论已关闭.