用了下CyclicBarrier,注意线程池中的线程数量设置,还有就是DB连接的时候,需要考虑单个DB能承受的最大连接数目和每个连接上能同时打开的cursor等限制,需要时可以通过jstack查看堆栈中关于等待锁的信息,同时注意在线程数/连接池中连接数以及任务数中找到性能平衡点
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ConPoolTest {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
long start = System.currentTimeMillis();
ExecutorService exec = Executors.newFixedThreadPool(5000);
CyclicBarrier barrier = new CyclicBarrier(5001);
for (int i = 0; i < 5000; i++) {
exec.execute(new TaskRun(barrier));
}
barrier.await();
System.out.println(ConnectionPool.connCnt);
ConnectionPool.cleanAll();
System.out.println(ConnectionPool.connCnt);
System.out.println(System.currentTimeMillis() - start);
exec.shutdown();
}
} class TaskRun implements Runnable {
CyclicBarrier barrier = null; TaskRun(CyclicBarrier barrier) {
this.barrier = barrier;
} @Override
public void run() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = ConnectionPool.getConnect();
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from t");
while (rs.next()) {
System.out.println(Thread.currentThread().getName() + " ... " + rs.getString(1));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
try {
if (stmt != null)
stmt.close();
if (rs != null)
rs.close();
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.TreeMap; //简单初始化固定数目的链接,需要用的时候过来随机拿一个
public class ConnectionPool {
private static List<Connection> connList = new ArrayList<Connection>();
static TreeMap<Integer, Integer> connCnt = new TreeMap<Integer, Integer>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
static {
int i = 0;
while (i++ < 100) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "system",
"*****");
connList.add(conn);
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
}
} public static synchronized Connection getConnect() throws ClassNotFoundException, SQLException {
Random random = new Random();
int idx = random.nextInt(100);
boolean isContains = connCnt.containsKey(idx);
if (isContains) {
int cnt = connCnt.get(idx);
connCnt.put(idx, cnt + 1);
} else {
connCnt.put(idx, 1);
}
return connList.get(idx);
} public static synchronized void cleanAll() {
for (Connection conn : connList) {
try {
conn.close();
connCnt.clear();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}