package com.flying.promotion.atomic.reference;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Ê×ÏÈËµÃ÷ÎªÊ²Ã´ÒªÓÐÒýÓÃµÄAtomic£º
 * 		ÒòÎªÒýÓÃÔÚ¸³ÖµµÄË²¼äÒ²»á´æÔÚ¶ÁÐ´µÄ²¢·¢£¬ËüÔÚÄÚ´æÀïÃæÀàËÆÓÚintºÍlongµÈÀàÐÍÊý¾ÝµÄ±ä»¯
 *      Ò»°ãÀ´Ëµ¶ÔÏó×÷ÎªÈ«¾ÖÐÅÏ¢µÄÇé¿ö½ÏÉÙ£¬µ«ÊÇÒ²ÄÑÃâÓÐ²¢·¢µÄÇé¿ö´æÔÚ£¬µ±È»ÓÐÐ©¼¯ºÏÀà±¾Éí½â¾öÁËÕâÐ©ÎÊÌâ£¬µ«ÊÇÈç¹ûÊÇµ¥¸ö¶ÔÏóµÄÌæ»»£¬¾Í»áÓÐÕâÐ©ÎÊÌâÁË
 *      ÀýÈç£ºÄÚ´æÖÐ¶à¸ö»º³åÇø×öÀ´»ØÇÐ»»Ð´²Ù×÷£¬ÇÐ»»µÄË²¼äÒÔ¼°ÆäËûÏß³Ì»ñÈ¡¶ÁµÄË²¼äÐèÒªµÃµ½×î×¼È·µÄÐÅÏ¢£¬Ê¹µÃÇÐ»»Ê±ÊÇÓÐÐ§µÄ¡£
 * 
 * Àý×Ó½á¹ûËµÃ÷£º100¸öÏß³ÌËæ»ú·ÃÎÊÕâ¸ö´úÂë£¬Ö»ÓÐÒ»¸öÏß³ÌÄÜ»ñÈ¡µ½Ëø¶Ô¶ÔÏó½øÐÐÐÞ¸Ä
 * Èô½«abc2µÄÄ¿±ê½á¹û¸ÄÎªabc£¬ÄÇÃ´Ã¿¸öÏß³Ì¶¼»áµÃµ½Ö´ÐÐ£¬ÒòÎª¶¼ÄÜ¶Ô²»³É¹¦£¬abc½«»áÔÚ³£Á¿³ØÖÐÎ¨Ò»µØÖ·
 * ¶ø½«Ä¿±ê¸ÄÎªnew String("abc")Ò²»áÖ»ÓÐÒ»¸öÐÞ¸Ä³É¹¦£¬ËµÃ÷±È½ÏµÄÊÇÒýÓÃ¶ø²»ÊÇÄÚÈÝ
 * @author zhongyin.xy
 *
 */
public class AtomicReferenceTest {

	/**
	 * Ïà¹Ø·½·¨ÁÐ±í
	 * @see AtomicReference#compareAndSet(Object, Object) ¶Ô±ÈÉèÖÃÖµ£¬²ÎÊý1£ºÔ­Ê¼Öµ£¬²ÎÊý2£ºÐÞ¸ÄÄ¿±êÒýÓÃ
	 * @see AtomicReference#getAndSet(Object) ½«ÒýÓÃµÄÄ¿±êÐÞ¸ÄÎªÉèÖÃµÄ²ÎÊý£¬Ö±µ½ÐÞ¸Ä³É¹¦ÎªÖ¹£¬·µ»ØÐÞ¸ÄÇ°µÄÒýÓÃ
	 */
	public final static AtomicReference <String>ATOMIC_REFERENCE = new AtomicReference<String>("abc");
	
	private final static Random RANDOM_OBJECT = new Random();
	
	public static void main(String []args) throws InterruptedException {
		final CountDownLatch startCountDownLatch = new CountDownLatch(1);
		Thread []threads = new Thread[20];
		for(int i = 0 ; i < 20 ; i++) {
			final int num = i;
			threads[i] = new Thread() {
				public void run() {
					String oldValue = ATOMIC_REFERENCE.get();
					try {
						startCountDownLatch.await();
						Thread.sleep(RANDOM_OBJECT.nextInt() & 1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if(ATOMIC_REFERENCE.compareAndSet(oldValue , oldValue + num)) {
						System.out.println("ÎÒÊÇÏß³Ì£º" + num + ",ÎÒ»ñµÃÁËËø½øÐÐÁË¶ÔÏóÐÞ¸Ä£¡");
					}
				}
			};
			threads[i].start();
		}
		Thread.sleep(200);
		startCountDownLatch.countDown();
		for(Thread thread : threads) {
			thread.join();
		}
		System.out.println("×îÖÕ½á¹ûÎª£º" + ATOMIC_REFERENCE.get());
	}
}
