1.Atomic的原子自增运算

1.

最好将thread.activeCount的值扩大一点儿,因为过小的话会导致内存切换的过于频繁,容易导致程序崩溃

运行结果如下:

代码源码:

import org.omg.PortableServer.THREAD_POLICY_ID;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Atomic变量自增运算测试
 */
public class AtomicTest {
    public static AtomicInteger race = new AtomicInteger(0);

    public static void increase() {
        race.incrementAndGet();
    }

    private static final int THREADS_COUNT = 20;


    public static void main(String[] args) throws Exception {
        Thread[] threads = new Thread[THREADS_COUNT]; //定义一组threas的数组集合
        for (int i = 0; i < THREADS_COUNT; i++) { //20个线程进行单个循环
            threads[i] = new Thread(new Runnable() {  //单个线程进行实现runable的操作
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++){
                        increase(); //对increase进行自增操作,执行结果如下,内部迭代的工程
                    }
                }
            });
            //启动当前状态的i线程,因此要写在for循环里面
            threads[i].start();
        }
        while(Thread.activeCount()>10);
        Thread.yield();
        System.out.println(race);//正确输出结果为10000(单个进程自增的次数)*20(总的进程数)
                                 //因此自增结果应该为200000,但是实际结果并不是,而是偏小
    }
}

先得出输出结果,如下;

代码如下:

import org.omg.PortableServer.THREAD_POLICY_ID;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Atomic变量自增运算测试
 */
public class AtomicTest {
    //public static AtomicInteger race = new AtomicInteger(0);
    public static int race = 1;
    public static void increase() {
        race++;
    }

    private static final int THREADS_COUNT = 20;


    public static void main(String[] args) throws Exception {
        Thread[] threads = new Thread[THREADS_COUNT]; //定义一组threas的数组集合
        for (int i = 0; i < THREADS_COUNT; i++) { //20个线程进行单个循环
            threads[i] = new Thread(new Runnable() {  //单个线程进行实现runable的操作
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++){
                        increase(); //对increase进行自增操作,执行结果如下,内部迭代的工程
                    }
                }
            });
            //启动当前状态的i线程,因此要写在for循环里面
            threads[i].start();
        }
        while(Thread.activeCount()>4);
        //Thread.yield();
        System.out.println(race);//正确输出结果为100(单个进程自增的次数)*20(总的进程数)
                                 //因此自增结果应该为2000,但是实际结果并不是,而是偏小
    }
}

//因此可知这种方法也是线程相对而言,并不是安全的。

但是AntomicInteger操作之后:

如下:

得出了正确的结果:

代码源码如下:

import org.omg.PortableServer.THREAD_POLICY_ID;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Atomic变量自增运算测试
 */
public class AtomicTest {
    public static AtomicInteger race = new AtomicInteger(0);
    public static void increase() {
        race.incrementAndGet();
    }

    private static final int THREADS_COUNT = 20;


    public static void main(String[] args) throws Exception {
        Thread[] threads = new Thread[THREADS_COUNT]; //定义一组threas的数组集合
        for (int i = 0; i < THREADS_COUNT; i++) { //20个线程进行单个循环
            threads[i] = new Thread(new Runnable() {  //单个线程进行实现runable的操作
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++){
                        increase(); //对increase进行自增操作,执行结果如下,内部迭代的工程
                    }
                }
            });
            //启动当前状态的i线程,因此要写在for循环里面
            threads[i].start();
        }
        while(Thread.activeCount()>2);
        //Thread.yield();
        System.out.println(race);//正确输出结果为100(单个进程自增的次数)*20(总的进程数)
                                 //因此自增结果应该为2000,但是实际结果并不是,而是偏小
    }
}

使用int进行定义的时候,race这是不安全的机制,详细代码,可以复制拿去验证,但是使用AtomicInteger尽享定义就不一样的了,因为其定义了race之后,调用方法,incrementAndGet()方法,但是该方法是原子性的可以确保其线程是安全的。

验证的时候,Thread.activeCount>不要设置的过大。这个

问题会专门写个专题扩展一下:

Thread.activeCount() 方法返回活动线程的当前线程的线程组中的数量,已你现在的程序(线程中间过程短,一下就结束了)所以你Thread.activeCount()时为1,你可以System.out.println(Thread.activeCount())控制台输出试试

1的话,当前线程组的书,数目为1,是会导致切换过快,计算机进行假死的情况的。

因此需要设置成2以及以上即可。

其中incrementAndGet()方法,跟进去,查看如下所示:

继承了Number类以及进行了序列化的操作:

final表明了这个是不可能轻易被继承的,一定程度保证了其原子性

然后再跟进一个getAndAddInt继续去跟进下一步:

对于getIntVolatile()这个方法进行跟进如下所示;

扩展如下所示:

1。native 是用做java 和其他语言(如c++)进行协作时用的
也就是native 后的函数的实现不是用java写的
2。既然都不是java,那就别管它的源代码了

猜你喜欢

转载自blog.csdn.net/qq_35561207/article/details/84325511