更新时间:2023-07-31 来源:黑马程序员 浏览量:

在Java中,"++"操作符(递增操作符)本身是原子操作,也就是说它在单线程环境下是线程安全的。原子操作是指一个操作在执行过程中不会被中断的操作,要么它执行完毕,要么它不执行。但是需要注意的是,当多个线程同时对同一个变量进行递增操作时,就不再是线程安全的,可能会出现竞态条件(race condition)问题。
  下面是一个简单的示例代码来演示多线程环境下递增操作的线程安全问题:
public class ThreadSafetyDemo {
    private static int counter = 0;
    public static void main(String[] args) {
        int numberOfThreads = 5;
        Thread[] threads = new Thread[numberOfThreads];
        for (int i = 0; i < numberOfThreads; i++) {
            threads[i] = new IncrementThread();
            threads[i].start();
        }
        // Wait for all threads to finish
        for (int i = 0; i < numberOfThreads; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Final counter value: " + counter);
    }
    static class IncrementThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100000; i++) {
                counter++;
            }
        }
    }
}在上面的代码中,我们创建了5个线程,每个线程都会对全局变量counter执行100000次递增操作。由于counter++不是原子操作,当多个线程同时对counter进行递增时,会出现竞态条件,导致最终结果可能小于预期的500000(5个线程每个线程增加了100000次)。
  为了保证线程安全,我们可以使用AtomicInteger类,它提供了原子操作的方式来处理这种情况:
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadSafetyDemo {
    private static AtomicInteger counter = new AtomicInteger(0);
    public static void main(String[] args) {
        int numberOfThreads = 5;
        Thread[] threads = new Thread[numberOfThreads];
        for (int i = 0; i < numberOfThreads; i++) {
            threads[i] = new IncrementThread();
            threads[i].start();
        }
        // Wait for all threads to finish
        for (int i = 0; i < numberOfThreads; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Final counter value: " + counter.get());
    }
    static class IncrementThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100000; i++) {
                counter.incrementAndGet();
            }
        }
    }
}在上述示例中,我们使用AtomicInteger来替代普通的int类型,AtomicInteger的incrementAndGet()方法确保了递增操作的原子性,避免了竞态条件问题。运行上面的代码,最终的counter值应该为500000,符合预期结果。
1024首播|39岁程序员逆袭记:不被年龄定义,AI浪潮里再迎春天
2025-10-241024程序员节丨10年同行,致敬用代码改变世界的你
2025-10-24【AI设计】北京143期毕业仅36天,全员拿下高薪offer!黑马AI设计连续6期100%高薪就业
2025-09-19【跨境电商运营】深圳跨境电商运营毕业22个工作日,就业率91%+,最高薪资达13500元
2025-09-19【AI运维】郑州运维1期就业班,毕业14个工作日,班级93%同学已拿到Offer, 一线均薪资 1W+
2025-09-19【AI鸿蒙开发】上海校区AI鸿蒙开发4期5期,距离毕业21天,就业率91%,平均薪资14046元
2025-09-19