JAVA中自增的线程安全问题

Java当中的 ++i 和 i++都是线程非安全的

以下多线程方式自增100得到的结果并不是100

public class Test {
    public static int num = 0;

   public void increase(){
        try {
            Thread.sleep(300);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        ++num;
    }
   public static void main(String[] args) throws InterruptedException {
        Test test = new Test();
        //创建100个线程执行+1操作,最终num = 100
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                     test.increase();
                }
            }).start();
        }
     //当前线程 > 2,除主线程外还有另外的线程,让出主线程CPU时间片
    //在idea中,除了主线程,还存在一个监控线程,所以,如果不存在其他线程的情况下,Thread,activeCount()=2

        while (Thread.activeCount() > 2){
            Thread.yield();
        }
        System.out.println(i);
    }
}

解决方法1:使用synchronized

public  synchronized void increase(){
        try {
            Thread.sleep(300);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        ++num;
    }

解决方法2:使用原子类

public static AtomicInteger i = new AtomicInteger(0);
//原子类方法,使用CAS,不用加锁便可避免线程安全问题
    public void atomIncrease(){
        try {
            Thread.sleep(300);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        i.incrementAndGet();
    }

 

posted @ 2022-03-02 15:13  procl51  阅读(369)  评论(0)    收藏  举报