needRestart 2019-04-23 14:24 采纳率: 100%
浏览 2190
已采纳

Runnable 中抛出java.lang.ArrayIndexOutOfBoundsException: -1

[已解决] 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

  • 写回答

2条回答 默认 最新

  • ꧁gaoKuo꧂ 2019-04-23 15:43
    关注

    Random 不要公用,改为线程内新建再试试

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 运筹学中在线排序的时间在线排序的在线LPT算法
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试,帮帮忙吧