线程安全实现自增


                                                       线程安全实现自增



package com.ywx.ssm.others;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程安全: 当多个线程访问某个类时, 这个类始终都能表现出正确的行为, 那么就称这个类是线程安全的。
 *
 */
public class ThreadSafeTest {

       public static int count = 0;
       public static Counter counter = new Counter();
       public static AtomicInteger atomicInteger = new AtomicInteger(0);
       volatile public static int countVolatile = 0;

    public static void main(String[] args) {
        // 保证所有线程执行完毕.
        final CountDownLatch cdl = new CountDownLatch(10);
        for(int i=0; i<10; i++) {
             new Thread() {
                 public void run() {
                     for (int j = 0; j < 1000; j++) {
                         count++;
                         counter.increment();
                         atomicInteger.getAndIncrement();
                         countVolatile++;
                    }
                    cdl.countDown();
                 }
             }.start();
        }
        try {
            cdl.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("static count: " + count);
        System.out.println("Counter: " + counter.getValue());
        System.out.println("AtomicInteger: " + atomicInteger.intValue());
        System.out.println("countVolatile: " + countVolatile);
    }
}

class Counter {

    private int value;

    public synchronized int getValue() {
        return value;
    }

    public synchronized int increment() {
        return value++;
    }

    public synchronized int decrement() {
        return --value;
    }
}



运行结果如下,每次运行结果都不一样,但是每次中间的两个都是10000.
static count: 9997
Counter: 10000
AtomicInteger: 10000
countVolatile: 9997


说明要解决自增操作在多线程环境下线程不安全的问题,可以选择使用Java提供的原子类或者使用synchronized同步方法。
而使用volatile关键字, 并不能解决非原子操作的线程安全性。
另外: 虽然递增操作++i看上去只是一个操作, 但这个操作并非原子的, 因而它并不会作为一个不可分割的操作来执行。
实际上它包含了三个独立的操作: 读取count的值, 将值加1, 然后将计算结果写入count. 
这是一个“读取 - 修改 - 写入”的操作序列, 并且其结果状态依赖于之前的状态。


补充:
volatile变量修饰的,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的。
volatile变量可用于提供线程安全, 但是应用场景非常局限: 多个变量之间或者某个变量的当前值与修改后值之间没有约束。
因此, 单独使用volatile还不足以实现计数器、互斥锁或任何具有与多个线程共享的变量。



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值