当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Java Atomic Variables用法及代码示例


多线程,共享实体主要会在以下情况下导致问题:并发性被合并。共享实体,例如,可变的对象或变量可能会被更改,这可能会导致程序的不一致或数据库。因此,在并发访问时处理共享实体变得至关重要。一个原子变量可以是这种情况下的替代方案之一。

Java提供原子类AtomicInteger,AtomicLong,AtomicBooleanAtomicReference。这些类的对象代表原子变量分别为 int、long、boolean 和对象引用。这些类包含以下方法。

  1. 设置(整数值):设置为给定值
  2. get():获取当前值
  3. 惰性设置(int值):最终设置为给定值
  4. CompareAndSet(int期望,int更新):如果当前值 == 预期值,则自动将该值设置为给定的更新值
  5. addAndGet(int delta):以原子方式将给定值添加到当前值
  6. decrementAndGet():以原子方式将当前值减一

例子:

// Atomic Variable
AtomicInteger var;

需要原子变量
考虑下面的例子:

Java


class Counter extends Thread {
    // Counter Variable
    int count = 0;
    // method which would be called upon
    // the start of execution of a thread
    public void run()
    {
        int max = 1_000_00_000;
        // incrementing counter
        // total of max times
        for (int i = 0; i < max; i++) {
            count++;
        }
    }
}
public class UnSafeCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();
        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");
        // Threads start executing
        first.start();
        second.start();
        // main thread will wait for
        // both threads to get completed
        first.join();
        second.join();
        // Printing final value of count variable
        System.out.println(c.count);
    }
}
输出:
137754082

在单线程环境中,上述类只会给出预期的结果。但当涉及到多线程环境时,可能会导致结果不一致。发生这种情况是因为更新 “var” 是通过三个步骤完成的:读取、更新和写入。如果两个或更多线程尝试同时更新该值,则它可能无法正确更新。

这个问题可以使用 Lock and Synchronization 解决,但效率不高。

1.使用锁类比或同步:同步或锁定可以解决我们的问题,但它会损害时间效率或性能。首先,它要求资源和线程调度程序来控制锁。其次,当多个线程尝试获取锁时,只有一个线程获胜,其余线程被挂起或阻塞。挂起或阻塞线程会对性能产生巨大影响。

Java


import java.io.*;
import java.util.concurrent.locks.*;
class Counter extends Thread {
    // Counter Variable
    int count = 0;
    // method which would be called upon
    // the start of execution of a thread
    public synchronized void run()
    {
        int max = 1_000_00_000;
        // incrementing counter total of max times
        for (int i = 0; i < max; i++) {
            count++;
        }
    }
}
public class SynchronizedCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();
        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");
        // Threads start executing
        first.start();
        second.start();
        // main thread will wait for both
        // threads to complete execution
        first.join();
        second.join();
        // Printing final value of count variable
        System.out.println(c.count);
    }
}
输出:
200000000

2.使用原子变量:

Java


import java.util.concurrent.atomic.AtomicInteger;
class Counter extends Thread {
    // Atomic counter Variable
    AtomicInteger count;
    // Constructor of class
    Counter()
    {
        count = new AtomicInteger();
    }
    // method which would be called upon
    // the start of execution of a thread
    public void run()
    {
        int max = 1_000_00_000;
        // incrementing counter total of max times
        for (int i = 0; i < max; i++) {
            count.addAndGet(1);
        }
    }
}
public class AtomicCounter {
    public static void main(String[] args)
        throws InterruptedException
    {
        // Instance of Counter Class
        Counter c = new Counter();
        // Defining Two different threads
        Thread first = new Thread(c, "First");
        Thread second = new Thread(c, "Second");
        // Threads start executing
        first.start();
        second.start();
        // main thread will wait for both
        // threads to complete execution
        first.join();
        second.join();
        // Printing final value of count variable
        System.out.println(c.count);
    }
}
输出:
200000000


相关用法


注:本文由纯净天空筛选整理自NiravTalaviya大神的英文原创作品 Atomic Variables in Java with Examples。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。