1 -
زمانی که میخواهیم عملیات های ساده روی یک متغیر داخل thread انجام دهیم یک شیئ atomic variable داخل آن نخ میسازیم و برای انجام عملیات از توابع داخل آن کلاس استفاده میکنیم.
این متغیر ها این خصوصیت را دارند که هنگامی که عملیاتی روی آن درحال اجراست thread دیگری اجرا نمیشود در نتیجه در محاسبه مقدار خطا ایجاد نمیشود.

2 -
AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference<T>

3 - Compare locks with atomic variables.
متغیر های اتمی برای عملیات های ساده استفاده میشود اما قفل برای عملیات های پیچیده تر استفاده میشود و برای چند متغیر استفاده میشود.

🎯Bonus Task:
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicDemo {

    private static int normalCounter = 0;
    private static AtomicInteger atomicCounter = new AtomicInteger(0);

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

        Thread[] threads = new Thread[10];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    normalCounter++;
                    atomicCounter.incrementAndGet();
                }
            });
        }

        for (Thread t : threads) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }

        System.out.println( normalCounter);
        System.out.println( atomicCounter.get());
    }
}