AtomicStampedReference、Integer缓存机制、Java自动装箱三大知识点

package com.jvm.cas;

import org.junit.Test;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * Created by ZhouChenmin on 2018/3/24.
 */
public class AtomicStampedReferenceTest {

    @Test
    public void simpleTest(){

        Integer  initRef = 1;
        Integer initStem = 1;
        AtomicStampedReference<Integer> data = new AtomicStampedReference(initRef,initStem);

        boolean ok = data.compareAndSet(1,2,1,2);
        System.out.println(ok);

        ok = data.compareAndSet(2,3,data.getStamp(),data.getStamp() + 1);
        System.out.println(ok);

        System.out.println(data.getReference());

    }


    @Test
    public void concurrentTest() throws InterruptedException {

        int  initRef = 1;
        int initStem = 1;
        final AtomicStampedReference<Integer> data = new AtomicStampedReference(initRef,initStem);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable r) {
                        Thread thread = new Thread(r);
                        thread.setDaemon(false);
                        return thread;
                    }
                });
        int threadSize = 5;
        final CountDownLatch countDownLatch = new CountDownLatch(threadSize);

        for (int i = 1 ;i <= threadSize ; i ++){

            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int j =0 ;j < 100 ; j ++){
                            incr(data);
                        }
                    }finally {
                        System.out.println(Thread.currentThread().getName()  + " has done the job");
                        countDownLatch.countDown();
                    }
                }
            });
        }

        try {
            countDownLatch.await(10,TimeUnit.SECONDS);
        } catch (InterruptedException e) {
        }

        System.out.println(countDownLatch.getCount());
        if (countDownLatch.getCount() > 0){
            System.out.println("依旧有线程在跑" + countDownLatch.getCount());
        }

        System.out.println(data.getReference());
        System.out.println(data.getStamp());

        /**
         * 既然还有线程没有跑完,并且也不是守护线程,为什么程序就结束了????????????????
         */

    }


    public void incr (final AtomicStampedReference<Integer> data){




        int mexRetry = 0;

        while (true){
            int value  = data.getReference();
            int stamp  = data.getStamp();

            if ( !data.compareAndSet(value , value+1 , stamp , stamp+1) ) {
                mexRetry++;
            }else {
                return;
            }
            if (mexRetry > 20){
                //throw new RuntimeException("retry count reach");
                try {
                    Thread.sleep(1000);
                    mexRetry= 0;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * testIncr
     */
    @Test
    public void testIncr (){
        int  initRef = 1;
        int initStem = 1;
        final AtomicStampedReference<Integer> data = new AtomicStampedReference(initRef,initStem);

        incr(data);
        incr(data);

        System.out.println(data.getReference());
        System.out.println(data.getStamp());
    }





}

期望输出501,结果输出128,请找出程序BUG,提示BUG在incr方法中。

  运行junit test concurrentTest()

猜你喜欢

转载自jdkleo.iteye.com/blog/2414691
今日推荐