循环创建线程任务造成数据混乱的原因

  贴个例子:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class TestThread2 {
    private static int nThreads = 2;

    private static ExecutorService executors = Executors.newFixedThreadPool(nThreads, new ThreadFactory() {
        
        private final String threadNamePrefix="si_query_task_";
        
        private final AtomicInteger count = new AtomicInteger(1);
        
        
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(Thread.currentThread().getThreadGroup(),r,threadNamePrefix + count.getAndIncrement());
            //t.setDaemon(true);
            return t;
        }
    });

    

    public static void main(String[] args) {
        
        for (int i = 0; i < 5; i++) {
            photo p=new photo();
            p.setA(i+"");
            p.setB("aaaa");
            if(i==3){
                p.setC("dddd");
            }else{
                p.setC("cccc");
            }
            task2 t=new task2();
            t.setPhoto(p);
            executors.execute(t);
            System.out.println(i);
        }

    }

    static class task2 implements Runnable{
        private photo photo;
        
        public photo getPhoto() {
            return photo;
        }
        public void setPhoto(photo photo) {
            this.photo = photo;
        }
        @Override
        public void run() {
            System.out.println(photo);
        }
        
    }
}

class photo{
    private String a;
    
    private String b;
    
    private String c;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

    @Override
    public String toString() {
        return "photo [a=" + a + ", b=" + b + ", c=" + c + "]";
    }
    
}

       结果:

 

问题会出现在这个实体类的创建,图里面的写法是正确的,不会造成数据混乱的情况,但是如果实体类photo的创建在for循环外面,就会出现问题了

         结果:

 

其实产生数据混乱的原因很简单:当对象传递给线程的时候,传的是内存地址,但是这个地址里面的数据是会被更改的,所以等到线程去操作这些数据的时候,就出问题了,但是对象重新创建就相当于新建了一个内存地址,就不会出现被更改了的情况

 

posted @ 2019-03-06 18:03  宇枫  阅读(1405)  评论(0编辑  收藏  举报