[已解决] SimpleDateFormat.format并发调用会有问题private SimpleDateFormat.StringBuffer format(Date date, StringBuffer toAppendTo, FieldDelegate delegate) 里面用了calendar.setTime(date);这玩意是全局的,后面还会调用它,所以并发时候会出问题。
Random中protected Random.next(int bits);采用AtomicLong的CAS操作并发时候不会出问题。
每个Task有自己的ArrayList实例,在多线程情况下每个ArrayList实例应该不存在并发写入啊,为没什么还报ArrayIndexOutOfBoundsException: -1
求助大神,网上找了好久没结果。
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static java.lang.System.out;
public class TestArrayList {
public static void main(String[] args){
TestArrayList t= new TestArrayList();
t.testInsertRows();
}
private static int millisecondOf1Day= 1000*3600*24;
private static int millisecondOf5Min= 1000*60*5;
private static final SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private final ExecutorService pool= Executors.newFixedThreadPool(8);
public void testInsertRows(){
Random random= new Random();
int taskId= 0;
for(int i=0; i< 8; i++){
taskId++;
pool.submit(new Task(taskId, 10000, null));
}
out.println("all submited!");
}
static class Task implements Runnable{
private Integer id;
private List<Bean> list;
private int rowCount;
private int count=0;
private Random random;
public Task(Integer id, Integer rowCount, Random random){
this.id= id;
this.list= new ArrayList<>(rowCount+1);
this.rowCount= rowCount;
// this.random= random;
this.random= new Random();
}
@Override
public void run() {
out.println("task:"+id+" is running! "+Thread.currentThread());
try{
for(int j=0; j< rowCount; j++ ){
Long randomTime= random.nextLong();
Date validityDate= new Date(randomTime- millisecondOf1Day),
startDate= new Date(randomTime),
endDate= new Date(randomTime+ 2*millisecondOf1Day);
Bean bean = new Bean();
bean.setField0("K0000033");
bean.setField1("0001");
bean.setField2(sdf.format(validityDate));
bean.setField3(new Double(0.0).toString());
bean.setField4(sdf.format(startDate));
bean.setField5(sdf.format(endDate));
list.add(bean);
}
out.println("list is prepared in thread:"+id);
Thread.sleep(millisecondOf5Min);//
out.println(count+" rows has been inserted in thread:"+id);
}catch (Exception e) {
synchronized (out) {
out.println("task:"+id+" in error"+Thread.currentThread());
e.printStackTrace();
out.println("task:"+id+" error info print completed");
}
}
}
}
}
class Bean{
private String field0;
private String field1;
private String field2;
private String field3;
private String field4;
private String field5;
private String field6;
/**
* @return the field0
*/
public String getField0() {
return field0;
}
/**
* @param field0 the field0 to set
*/
public void setField0(String field0) {
this.field0 = field0;
}
/**
* @return the field1
*/
public String getField1() {
return field1;
}
/**
* @param field1 the field1 to set
*/
public void setField1(String field1) {
this.field1 = field1;
}
/**
* @return the field2
*/
public String getField2() {
return field2;
}
/**
* @param field2 the field2 to set
*/
public void setField2(String field2) {
this.field2 = field2;
}
/**
* @return the field3
*/
public String getField3() {
return field3;
}
/**
* @param field3 the field3 to set
*/
public void setField3(String field3) {
this.field3 = field3;
}
/**
* @return the field4
*/
public String getField4() {
return field4;
}
/**
* @param field4 the field4 to set
*/
public void setField4(String field4) {
this.field4 = field4;
}
/**
* @return the field5
*/
public String getField5() {
return field5;
}
/**
* @param field5 the field5 to set
*/
public void setField5(String field5) {
this.field5 = field5;
}
/**
* @return the field6
*/
public String getField6() {
return field6;
}
/**
* @param field6 the field6 to set
*/
public void setField6(String field6) {
this.field6 = field6;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Bean [field0=" + field0 + ", field1=" + field1 + ", field2=" + field2 + ", field3=" + field3
+ ", field4=" + field4 + ", field5=" + field5 + ", field6=" + field6 + "]";
}
}
task:1 is running! Thread[pool-1-thread-1,5,main]
task:4 is running! Thread[pool-1-thread-4,5,main]
task:3 is running! Thread[pool-1-thread-3,5,main]
task:2 is running! Thread[pool-1-thread-2,5,main]
task:5 is running! Thread[pool-1-thread-5,5,main]
task:6 is running! Thread[pool-1-thread-6,5,main]
all submited!
task:7 is running! Thread[pool-1-thread-7,5,main]
task:8 is running! Thread[pool-1-thread-8,5,main]
task:7 in errorThread[pool-1-thread-7,5,main]
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Calendar.getDisplayName(Unknown Source)
at java.text.SimpleDateFormat.subFormat(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.DateFormat.format(Unknown Source)
at com.haimian.test.concurrent.TestArrayList$Task.run(TestArrayList.java:64)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
task:7 error info print completed
task:8 in errorThread[pool-1-thread-8,5,main]
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Calendar.getDisplayName(Unknown Source)
at java.text.SimpleDateFormat.subFormat(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.DateFormat.format(Unknown Source)
at com.haimian.test.concurrent.TestArrayList$Task.run(TestArrayList.java:65)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
task:8 error info print completed
task:4 in errorThread[pool-1-thread-4,5,main]
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Calendar.getDisplayName(Unknown Source)
at java.text.SimpleDateFormat.subFormat(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.DateFormat.format(Unknown Source)
at com.haimian.test.concurrent.TestArrayList$Task.run(TestArrayList.java:62)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
task:4 error info print completed
task:1 in errorThread[pool-1-thread-1,5,main]
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Calendar.getDisplayName(Unknown Source)
at java.text.SimpleDateFormat.subFormat(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.DateFormat.format(Unknown Source)
at com.haimian.test.concurrent.TestArrayList$Task.run(TestArrayList.java:64)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
task:1 error info print completed
task:5 in errorThread[pool-1-thread-5,5,main]
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Calendar.getDisplayName(Unknown Source)
at java.text.SimpleDateFormat.subFormat(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.DateFormat.format(Unknown Source)
at com.haimian.test.concurrent.TestArrayList$Task.run(TestArrayList.java:65)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
task:5 error info print completed
task:3 in errorThread[pool-1-thread-3,5,main]
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Calendar.getDisplayName(Unknown Source)
at java.text.SimpleDateFormat.subFormat(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.DateFormat.format(Unknown Source)
at com.haimian.test.concurrent.TestArrayList$Task.run(TestArrayList.java:64)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
task:3 error info print completed
task:6 in errorThread[pool-1-thread-6,5,main]
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Calendar.getDisplayName(Unknown Source)
at java.text.SimpleDateFormat.subFormat(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.SimpleDateFormat.format(Unknown Source)
at java.text.DateFormat.format(Unknown Source)
at com.haimian.test.concurrent.TestArrayList$Task.run(TestArrayList.java:64)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
task:6 error info print completed
list is prepared in thread:2