用了下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(); } } } }