局部变量一定线程安全吗

局部变量, 如果是基本类型或是包装类型, 依然不能通过多线程改变其值, 如果是对象, 则其属性值是线程不安全的

demo1:

public void compute(LocalDate date){

        //在切换租户时,只有当前线程的第一个租户id设置有效,或者说一个线程内无法切换数据源
        TenantContext.set("saas_base");
        List<TenantInfo> tenantInfoDtos = tenantInfoDao.getByStatus(1);
        CountDownLatch status = new CountDownLatch(tenantInfoDtos.size());
        tenantInfoDtos.forEach(x->threadPoolTaskExecutor.execute(new InnerThread(x.getTenantId(), date, status)));
        try {
            status.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info(date+":DailyDataReportTask执行完成");
    }

demo2: 输出为0

@Test
    public void textTask(){
        int i = 0;
        for(int j=0;j<10000;j++){
        pool.execute(new InnerThread(i));}
        try {
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(i);
    }

    class InnerThread implements Runnable{
        public int i;
        public InnerThread(int i){
            this.i=i;
        }
        public void run(){
            i=i+1;
        }
    }

demo3 输出9963

@Setter
@Getter
@AllArgsConstructor
public class Testsss {

    int i;

}
  @Test
    public void textTask(){
        Testsss t = new Testsss(0);
        for(int j=0;j<10000;j++){
        pool.execute(new InnerThread(t));}
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(t.getI());
    }

    class InnerThread implements Runnable{
        public Testsss t;
        public InnerThread(Testsss t){
            this.t=t;
        }
        public void run(){
            t.setI(t.getI()+1);
        }
    }

demo4: 输出10000

    @Test
    public void textTask() {
        Testsss t = new Testsss(0);
        for (int j = 0; j < 10000; j++) {
            pool.execute(new InnerThread(t));
        }
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(t.getI());
    }

    class InnerThread implements Runnable {
        public Testsss t;

        public InnerThread(Testsss t) {

            this.t = t;
        }

        public void run() {
            synchronized (t) {
                t.setI(t.getI() + 1);
            }

        }
    }

 

展开阅读全文

没有更多推荐了,返回首页