Java 在多线程代码中访问数组列表的每个线程

Java 在多线程代码中访问数组列表的每个线程,java,multithreading,thread-safety,race-condition,Java,Multithreading,Thread Safety,Race Condition,我正在从事一个项目,在该项目中,我在不同的数据库中有两个具有不同模式的表。这意味着我有两个不同的连接参数用于使用JDBC连接这两个表- 假设下面是config.property文件 TABLES: table1 table2 #For Table1 table1.url: jdbc:mysql://localhost:3306/garden table1.user: gardener table1.password: shavel table1.driver: jdbc-driver tabl

我正在从事一个项目,在该项目中,我在不同的数据库中有两个具有不同模式的表。这意味着我有两个不同的连接参数用于使用JDBC连接这两个表-

假设下面是config.property文件

TABLES: table1 table2

#For Table1
table1.url: jdbc:mysql://localhost:3306/garden
table1.user: gardener
table1.password: shavel
table1.driver: jdbc-driver
table1.percentage: 80
table1.columns: COL1,COL2,COl3,Col4,COL5

#For Table2
table2.url: jdbc:mysql://otherhost:3306/forest
table2.user: forester
table2.password: axe
table2.driver: jdbc-driver
table2.percentage: 20
table1.columns: COL10,COL11,COl12,Col13,COL14
下面的方法将读取上面的
config.properties
文件,并为每个表创建一个
TableConnectionInfo
对象

private static void readPropertyFile() throws IOException {

    prop.load(LnPRead.class.getClassLoader().getResourceAsStream("config.properties"));

    tableNames = Arrays.asList(prop.getProperty("TABLES").trim().split(","));

    for (String arg : tableNames) {

        TableConnectionInfo ci = new TableConnectionInfo();
        ArrayList<String> columns = new ArrayList<String>();

        String table = prop.getProperty(arg + ".table").trim();
        columns = new ArrayList<String>(Arrays.asList(prop.getProperty(arg + ".columns").split(",")));

        ci.setTableName(table);
        ci.setColumns(columns);

        tableList.put(arg, ci);
    }
}   
现在,我正在为指定数量的线程创建
ExecutorService
,并将这个
tableList
对象(我通过读取
config.property文件创建的)传递给
任务类的构造函数
,然后这个
tableList
对象将不会被任何线程修改,只有每个线程将访问这些值-

// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(10);

long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun * 60 * 1000);

for (int i = 0; i < threads; i++) {
    service.submit(new Task(endTime, tableList));
}
//创建具有给定大小的线程池
ExecutorService=Executors.newFixedThreadPool(10);
long startTime=System.currentTimeMillis();
长结束时间=开始时间+(运行持续时间*60*1000);
对于(int i=0;i
下面是我实现Runnable接口的任务类

class Task implements Runnable {

    private static Random random = new SecureRandom();
    private final long endTime;
    private final LinkedHashMap<String, TableConnectionInfo> tableLists;

    public Task(long endTime, LinkedHashMap<String, TableConnectionInfo> tableList) {
        this.endTime = endTime;
        this.tableLists = tableList;
    }

    @Override
    public void run() {

        while (System.currentTimeMillis() <= endTime) {

            .....

            double randomNumber = random.nextDouble() * 100.0;
            TableConnectionInfo table = selectRandomTable(randomNumber);

            /* Below line is Thread Safe right? 
             * And there won't be any issue with it? As I am doing
             * table.getColumns which will returns me an ArrayList of columns
             */
            final String columnsList = getTableColumns(table.getColumns());

            ....
        }
      }

     private String getTableColumns(final List<String> columns) {

      ...

     }
}
类任务实现可运行{
private static Random=new SecureRandom();
私人最终长时间;
私人最终LinkedHashMap表格列表;
公共任务(长结束时间,LinkedHashMap表列表){
this.endTime=endTime;
this.tableList=tableList;
}
@凌驾
公开募捐{

while(System.currentTimeMillis()这在技术上是线程安全的,只要基础ArrayList在初始构造后不发生更改。本例中的每个线程都将引用ArrayList的相同实例

如果将来有计划使这些表列可变,这将导致问题。如果此列表可变,我将构造一个新的列表和指针交换,或者使用java.util.concurrent.*类保存列列表

class Task implements Runnable {

    private static Random random = new SecureRandom();
    private final long endTime;
    private final LinkedHashMap<String, TableConnectionInfo> tableLists;

    public Task(long endTime, LinkedHashMap<String, TableConnectionInfo> tableList) {
        this.endTime = endTime;
        this.tableLists = tableList;
    }

    @Override
    public void run() {

        while (System.currentTimeMillis() <= endTime) {

            .....

            double randomNumber = random.nextDouble() * 100.0;
            TableConnectionInfo table = selectRandomTable(randomNumber);

            /* Below line is Thread Safe right? 
             * And there won't be any issue with it? As I am doing
             * table.getColumns which will returns me an ArrayList of columns
             */
            final String columnsList = getTableColumns(table.getColumns());

            ....
        }
      }

     private String getTableColumns(final List<String> columns) {

      ...

     }
}