Runnable实现类的成员变量之线程安全问题


一. 先上结论

  • 当多个线程共用一个Runnable实现类的对象numRunnable时(Thread thread = new Thread(numRunnable,"thread"+i)),Runnable实现类的成员变量是线程不安全的!

二. 问题复现

public class Test {
    public static void main(String[] args) {
       int total = insertDataToTN(100,1);
       System.out.println("总:"+total); // 输出结果(每次结果不一样):427775

    }

    public static int insertDataToTN(int threadCount, final int cycleCount){

        class NumRunnable implements Runnable{
            int totalSum = 0;

            public void run(){
                for(int i = 0 ; i<10000;i++){
                    totalSum++;
                }
            }

        }

        NumRunnable numRunnable = new NumRunnable();
        List<Thread> threads = new ArrayList<Thread>();
        for(int i=0;i<threadCount;i++) {
            Thread thread = new Thread(numRunnable,"thread"+i);
            thread.start();
            threads.add(thread);
        }

        for(Thread tThread:threads){
            try {
                tThread.join();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return numRunnable.totalSum;
    }
}

三. 解决方法

1. 法1:使用原子类AtomicInteger

public class Test {
    public static void main(String[] args) {
        AtomicInteger a = insertDataToTN(100,1);
        System.out.println(a); // 输出结果:1000000
    }

    public static AtomicInteger insertDataToTN(int threadCount, final int cycleCount){

        class NumRunnable implements Runnable{
            AtomicInteger totalSum = new AtomicInteger(0);

            public void run(){
                for(int i = 0 ; i<10000;i++){
                    totalSum.addAndGet(1);
                }
            }
        }

        NumRunnable numRunnable = new NumRunnable();
        List<Thread> threads = new ArrayList<Thread>();
        for(int i=0;i<threadCount;i++) {
            Thread thread = new Thread(numRunnable,"thread"+i);
            thread.start();
            threads.add(thread);
        }

        for(Thread tThread:threads){
            try {
                tThread.join();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        return numRunnable.totalSum;
    }
}

2. 法2:使用synchronized关键字

public class Test {
    public static void main(String[] args) {
        int total = insertDataToTN(100,1);
        System.out.println("总:"+total); // 输出结果:1000000
    }

    public static int insertDataToTN(int threadCount, final int cycleCount){

        class NumRunnable implements Runnable{
             int totalSum = 0;

            public void run(){
                for(int i = 0 ; i<10000;i++){
                    add();
                }
            }

            public synchronized void add(){
                totalSum++;
            }

        }

        NumRunnable numRunnable = new NumRunnable();
        List<Thread> threads = new ArrayList<Thread>();
        for(int i=0;i<threadCount;i++) {
            Thread thread = new Thread(numRunnable,"thread"+i);
            thread.start();
            threads.add(thread);
        }

        for(Thread tThread:threads){
            try {
                tThread.join();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        return numRunnable.totalSum;

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值