美文网首页
Java中的原子操作

Java中的原子操作

作者: 堤岸小跑 | 来源:发表于2017-10-31 13:59 被阅读0次

什么是原子操作?
所谓原子操作,就是"不可中断的一个或一系列操作" , 在确认一个操作是原子的情况下,多线程环境里面,我们可以避免仅仅为保护这个操作在外围加上性能昂贵的锁,甚至借助于原子操作,我们可以实现互斥锁。 很多操作系统都为int类型提供了+-赋值的原子操作版本,比如 NT 提供了 InterlockedExchange 等API, Linux/UNIX也提供了atomic_set 等函数。

关于java中的原子性?
原子性可以应用于除long和double之外的所有基本类型之上的“简单操作”。对于读取和写入出long double之外的基本类型变量这样的操作,可以保证它们会被当作不可分(原子)的操作来操作。 因为JVM的版本和其它的问题,其它的很多操作就不好说了,比如说++操作在C++中是原子操作,但在Java中就不好说了。 另外,Java提供了AtomicInteger等原子类。再就是用原子性来控制并发比较麻烦,也容易出问题。

1)除long和double之外的基本类型的赋值操作
2)所有引用reference的赋值操作
3)java.concurrent.Atomic.* 包中所有类的一切操作
count++不是原子操作,是3个原子操作组合
1.读取主存中的count值,赋值给一个局部成员变量tmp
2.tmp+1
3.将tmp赋值给count
可能会出现线程1运行到第2步的时候,tmp值为1;这时CPU调度切换到线程2执行完毕,count值为1;切换到线程1,继续执行第3步,count被赋值为1------------结果就是两个线程执行完毕,count的值只加了1;
还有一点要注意,如果使用AtomicInteger.set(AtomicInteger.get() + 1),会和上述情况一样有并发问题,要使用AtomicInteger.getAndIncrement()才可以避免并发问题

package thread.Atomic;

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerTest  {

    public final static AtomicInteger TEST_INTEGER = new AtomicInteger(1);

    public static void main(String []args) throws InterruptedException {
        final Thread []threads = new Thread[10];
        for(int i = 0 ; i < 10 ; i++) {
            final int num = i;
            threads[i] = new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    int now = TEST_INTEGER.incrementAndGet();
                    System.out.println("我是线程:" + num + ",我得到值了,增加后的值为:" + now);
                }
            };
            threads[i].start();
        }
        for(Thread t : threads) {
            t.join();
        }
        System.out.println("最终运行结果:" + TEST_INTEGER.get());
    }
}

运行结果:

我是线程:1,我得到值了,增加后的值为:3
我是线程:0,我得到值了,增加后的值为:2
我是线程:9,我得到值了,增加后的值为:4
我是线程:4,我得到值了,增加后的值为:9
我是线程:5,我得到值了,增加后的值为:8
我是线程:6,我得到值了,增加后的值为:7
我是线程:8,我得到值了,增加后的值为:5
我是线程:7,我得到值了,增加后的值为:6
我是线程:3,我得到值了,增加后的值为:10
我是线程:2,我得到值了,增加后的值为:11
最终运行结果:11

最终运行结果:11

相关文章

网友评论

      本文标题:Java中的原子操作

      本文链接:https://www.haomeiwen.com/subject/djrbpxtx.html