在Java中,AtomicInteger是一个原子类

今天我们将在Java中研究AtomicInteger。原子操作是在单个任务单元中进行的操作,而不受其他操作的干扰。在多线程环境中,原子操作是必需的,以避免数据不一致。

原子整数

让我们创建一个简单的多线程程序,每个线程都会将共享计数变量增加4次。因此,如果有两个线程,当它们完成后计数值应该是8。 JavaAtomic.java

package com.Olivia.concurrency;

public class JavaAtomic {

    public static void main(String[] args) throws InterruptedException {

        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Processing count=" + pt.getCount());
    }

}

class ProcessingThread implements Runnable {
    private int count;

    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            processSomething(i);
            count++;
        }
    }

    public int getCount() {
        return this.count;
    }

    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

如果您运行上述程序,您会注意到计数值在5、6、7、8之间变化。原因是因为count++不是原子操作。因此,当一个线程读取并递增它的值时,另一个线程已经读取了旧的值,导致结果错误。为了解决这个问题,我们必须确保对count的增量操作是原子的,我们可以使用Synchronization来实现这一点,但是Java 5的java.util.concurrent.atomic提供了包装类用于int和long,可以在不使用Synchronization的情况下实现原子操作。

Java中的AtomicInteger示例

这是更新后的程序,它总是以 count 值为8输出,因为 AtomicInteger 方法 incrementAndGet() 通过原子性地将当前值加一来实现。

package com.Olivia.concurrency;

import java.util.concurrent.atomic.AtomicInteger;

public class JavaAtomic {

    public static void main(String[] args) throws InterruptedException {

        ProcessingThread pt = new ProcessingThread();
        Thread t1 = new Thread(pt, "t1");
        t1.start();
        Thread t2 = new Thread(pt, "t2");
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Processing count=" + pt.getCount());
    }
}

class ProcessingThread implements Runnable {
    private AtomicInteger count = new AtomicInteger();

    @Override
    public void run() {
        for (int i = 1; i < 5; i++) {
            processSomething(i);
            count.incrementAndGet();
        }
    }

    public int getCount() {
        return this.count.get();
    }

    private void processSomething(int i) {
        // processing some job
        try {
            Thread.sleep(i * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

使用并发类进行原子操作的好处是我们不需要担心同步问题,这提高了代码的可读性并降低了出错的机会。此外,原子操作并发类被认为比涉及锁定资源的同步更高效。

发表回复 0

Your email address will not be published. Required fields are marked *


广告
将在 10 秒后关闭
bannerAds