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 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64
  • ¥15 iOS 自定义输入法-第三方输入法
  • ¥15 很想要一个很好的答案或提示
  • ¥15 扫描项目中发现AndroidOS.Agent、Android/SmsThief.LI!tr
  • ¥15 怀疑手机被监控,请问怎么解决和防止
  • ¥15 Qt下使用tcp获取数据的详细操作
  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区
  • ¥15 在grasshopper里DrawViewportWires更改预览后,禁用电池仍然显示