为什么我的ScheduledExecutorService这样工作?

时间:2018-08-18 07:09:51

标签: java multithreading

我的线程程序无法正常工作,因为我希望它可以正常工作。

首先是我的主类,从那里开始我的线程:

import static java.lang.Thread.currentThread;

public class Main {

public static void main(String[] args) throws IOException, NamingException, ClassNotFoundException {

    Properties property = new Properties();

    property.load(new FileReader(new File(args[0])));

    DataSource ds = DataSource.newInstance(property);
    Class.forName("org.postgresql.Driver");

    ConnectionPool connectionPool = new ConnectionPool();
    System.out.println(currentThread().getName());
    ConnectionPoolManager manager = new ConnectionPoolManager(connectionPool, ds);
    manager.start();

    }

}

这是我的ConnectionPool类

package com.telbook.connectionPooling;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ConnectionPool {

private List<PoolObject> poolObjects = new ArrayList<>();

public List<PoolObject> getPoolObjects() {
    return poolObjects;
}

public void setPoolObjects(List<PoolObject> poolObjects) {
    this.poolObjects = poolObjects;
}

public void put(Connection connection) {
    PoolObject poolObject = new PoolObject();
    poolObject.setConnection(connection);
    poolObjects.add(poolObject);
}

public Connection getConnection() throws SQLException {
    for (PoolObject object: poolObjects) {
        if (!object.getInUse() && object.getConnection()!=null) {
            if (!object.getConnection().isClosed()) {
                if (object.getConnection().isValid(50)) {
                    object.setInUse(true);
                    return object.getConnection();
                }
            }
        }
    }

    return null;
}

}

这是ConnectionPoolManager:

package com.telbook.connectionPooling;

import java.io.IOException;
import java.sql.*;
import java.util.Iterator;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ConnectionPoolManager extends Thread {

private ConnectionPool connectionPool;
private DataSource dataSource;

public ConnectionPoolManager(ConnectionPool connectionPool, DataSource dataSource) throws IOException, ClassNotFoundException {

    this.connectionPool = connectionPool;
    this.dataSource = dataSource;

}

@Override
public void run() {

    for (int i=0; i<4; i++) {

        Thread thread = new Thread(new Runnable() {
            public void run() {
                System.out.println(currentThread().getName());

                try {

                    Connection conn = DriverManager.getConnection(dataSource.getUrl(), dataSource.getLogin(), dataSource.getPassword());//anonymous classes

                    System.out.println("Connection is created");
                    connectionPool.put(conn);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }


    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
    executorService.scheduleWithFixedDelay(new Runnable() {
                                               @Override
                                               public void run() {

                                                   List<PoolObject> poolObj = connectionPool.getPoolObjects();
                                                   int count = 1;
                                                   for(int i = 0; i<poolObj.size(); i++){
                                                       System.out.println("PoolObject"+" "+i);
                                                   }
                                               }
                                           } , 3, 5, TimeUnit.SECONDS
    );

}
}
我创建了4个池对象,将它们添加到ArrayList中,然后使用ScheduledExecutorService进行检查 如果我的ArrayList中恰好有4个池对象。 这是我的输出:

Thread-1
Thread-2
Thread-3
Thread-4
Connection is created
Connection is created
Connection is created
Connection is created
PoolObject 0
PoolObject 1
PoolObject 2
PoolObject 3
PoolObject 0
...
and again shows PoolObject from 0

有时候在3个或2个POOLOBJECT中产生了4个POOLOBJECT, 看起来像这样:

Thread-1
Thread-2
Thread-3
Thread-4
Connection is created
Connection is created
Connection is created
Connection is created
PoolObject 0
PoolObject 1
PoolObject 2
PoolObject 0
...
and again shows poolObjec from 0 which means,
that ScheduledExecutorService doesn't prints all poolObjects
from my ArrayList. There should be 4 PoolObjects.

为什么呢?为什么没有显示我创建的所有4个池对象?

1 个答案:

答案 0 :(得分:0)

ArrayList不安全,计划的线程池中的线程可能无法获取最新元素,请尝试使用线程安全版本List

private List<PoolObject> poolObjects = Collections.synchronizedList(new ArrayList<PoolObject>());