多线程学习-原子性(1)-Atomic

记录自己基于SpringBoot对多线程并发进行学习

一.准备工作

配置SpringBoot,在GIT上创建项目,将创建导入本地

测试Spring是否启动成功,测试是否返回test

写了4个annotations,用来表示安全和不安全,推荐和不推荐写法

其中使用了lombok

二.正式开始

线程安全性

    定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式,或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为.那么就称这个类时线程安全的

    体现方面: 原子性:提供了互斥访问,同一时刻只能有一个线程来对它进行操作

                    可见性:一个线程对主内存的修改可以及时的被其他线程观察到

                    有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排的存在,该观察结果一般杂乱无序

                原子性-AtomicInteger    使用example1和example2说明    注意Semaphore的使用

//example2
@ThreadSafe
@Slf4j
public class CoutntExample2 {
    //请求总数
    public static int clientTotal=15000;
    //同时并发执行的线程数
    public static int threadTotal=20;

    public static AtomicInteger count=new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        ThreadFactory threadFactory = new ThreadFactoryBuilder().
                setNameFormat("Example1").build();
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(
                10, 50, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingDeque<Runnable>(1024), threadFactory,
                new ThreadPoolExecutor.AbortPolicy());
        Semaphore semaphore = new Semaphore(threadTotal);
        CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int i = 0; i <clientTotal ; i++) {
            executorService.execute(()->{
                try {
                    semaphore.acquire();
                    add();
                    semaphore.release();
                }catch (Exception e){
                    log.error("exception",e);
                }
                countDownLatch.countDown();
            });

        }
        countDownLatch.await();
        executorService.shutdown();
        log.info("count:{}",count.get());

    }
    public static void add(){
        count.incrementAndGet();
    }
}

    其中查看 incrementAndGet()源码

    再看getAndAddInt()

    

其中compareAndSwapInt为一个native方法

    三个参数分别为,var变量,取出当前var变量的valueOffset,取出的值var5,若相等的话,var5的值=var5+var4

java.util.concurrent.RejectedExecutionException异常          

1.你的线程池ThreadPoolExecutor 显示的shutdown()之后,再向线程池提交任务的时候。如果你配置的拒绝策略是AbortPolicy的话,这个异常就会抛出来。

2.队列满了,而且池中的线程数也达到了最大线程数,所以新添加的任务被拒绝了。
这种情况,可以调整一下线程池的策略


                    -AtomicLong和LongAdder包

                    对应优点:LongAdder在AtomicLong的基础上,将单点的更新压力分散到各个节点上,在低并发的时候,通过对base的直接更新,保证性能和AtomicLong基本一致;在高并发的时候通过分散提高性能.

                        缺点:统计的时候,若有并发更新,可能会导致统计的数据有些误差(cell累加)

                        实际使用中,在处理高并发的数据时可以优先使用LongAdder而不是AtomicLong,在线程竞争很低的时候推荐使用AtomicLong.序列号生成需要准确的数值,应该使用AtomicLong

                    -AtomicReference和AtomicIntergerFieldUpdeter的使用

                    -AtomicStampReference:    CAS的ABA问题解决(版本号加1)

                    -AtomicLongArray:    维护的一个数组,额外多一个索引值去更新

                    -AtomicBoolean:    若希望某段代码执行一次,使用此



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值