一个使用AtomicInteger完成的Java线程同步的例子

295 阅读1分钟
package thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomIntTest {
	private AtomicInteger atomicI = new AtomicInteger(0);

	private int i = 0;
	private int unsafe = 0;
	
	public static void main(String[] args) {
		final AtomIntTest cas = new AtomIntTest();
		final int TOTAL_THREAD_NUM = 10;
		List<Thread> ts = new ArrayList<Thread>();

		long start = System.currentTimeMillis();
		for (int j = 0; j < TOTAL_THREAD_NUM; j++) {
			Thread t = new Thread(new Runnable() {
				@Override
				public void run() {
					Thread.currentThread().setName(AtomIntTest.class.getName() + Thread.currentThread().getId());
					for (int i = 0; i < 1000; i++) {
						cas.count(); // i++
						cas.safeCount();
						cas.unsafeCount();
					}
					System.out.println("Thread name: " + Thread.currentThread().getName());
				}
			});
			ts.add(t);
		}
		System.out.println("total thread number: " + ts.size());

		for (Thread t : ts) { // start 600 threads
			t.start();
		}

		// 等待所有线程执行完成
		for (Thread t : ts) {
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		System.out.println("safe via synchronized: " + cas.i);
		System.out.println("safe: " + cas.atomicI.get());
		System.out.println("unsafe: " + cas.unsafe);
		System.out.println(System.currentTimeMillis() - start);
	}

	/**
	 * 
	 * 使用CAS实现线程安全计数器
	 */
	private void safeCount() {
		for (;;) {
			int i = atomicI.get();
			boolean suc = atomicI.compareAndSet(i, ++i);
			if (suc) {
				break;
			}
		}
	}

	/**
	 * 
	 * 非线程安全计数器
	 */

	synchronized private void count() {
		i++;
	}
	
	private void unsafeCount() {
		unsafe++;
	}
}

输出:

total thread number: 10
Thread name: thread.AtomIntTest13
Thread name: thread.AtomIntTest22
Thread name: thread.AtomIntTest17
Thread name: thread.AtomIntTest15
Thread name: thread.AtomIntTest18
Thread name: thread.AtomIntTest14
Thread name: thread.AtomIntTest16
Thread name: thread.AtomIntTest20
Thread name: thread.AtomIntTest21
Thread name: thread.AtomIntTest19
safe via synchronized: 10000
safe: 10000
unsafe: 9782
9