循环创建线程任务造成数据混乱的原因
贴个例子:
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循环外面,就会出现问题了
结果:
其实产生数据混乱的原因很简单:当对象传递给线程的时候,传的是内存地址,但是这个地址里面的数据是会被更改的,所以等到线程去操作这些数据的时候,就出问题了,但是对象重新创建就相当于新建了一个内存地址,就不会出现被更改了的情况