服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - 用于App服务端的MySQL连接池(支持高并发)

用于App服务端的MySQL连接池(支持高并发)

2020-05-29 16:19MYSQL教程网 Mysql

这篇文章主要介绍了用于App服务端的MySQL连接池,并支持高并发,感兴趣的小伙伴们可以参考一下

本文向大家介绍了简单的MySQL连接池,用于App服务端比较合适,分享给大家供大家参考,具体内容如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/**
 * 连接池类
 */
package com.junones.test;
 
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
 
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
 
public class MySQLPool {
  private static volatile MySQLPool pool;
  private MysqlDataSource ds;
  private Map<Connection, Boolean> map;
 
  private String url = "jdbc:mysql://localhost:3306/test";
  private String username = "root";
  private String password = "root1234";
  private int initPoolSize = 10;
  private int maxPoolSize = 200;
  private int waitTime = 100;
   
  private MySQLPool() {
    init();
  }
   
  public static MySQLPool getInstance() {
    if (pool == null) {
      synchronized (MySQLPool.class) {
        if(pool == null) {
          pool = new MySQLPool();
        }
      }
    }
    return pool;
  }
   
  private void init() {
    try {
      ds = new MysqlDataSource();
      ds.setUrl(url);
      ds.setUser(username);
      ds.setPassword(password);
      ds.setCacheCallableStmts(true);
      ds.setConnectTimeout(1000);
      ds.setLoginTimeout(2000);
      ds.setUseUnicode(true);
      ds.setEncoding("UTF-8");
      ds.setZeroDateTimeBehavior("convertToNull");
      ds.setMaxReconnects(5);
      ds.setAutoReconnect(true);
      map = new HashMap<Connection, Boolean>();
      for (int i = 0; i < initPoolSize; i++) {
        map.put(getNewConnection(), true);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
   
  public Connection getNewConnection() {
    try {
      return ds.getConnection();
    } catch (SQLException e) {
      e.printStackTrace();
    }
    return null;
  }
   
  public synchronized Connection getConnection() {
    Connection conn = null;
    try {
      for (Entry<Connection, Boolean> entry : map.entrySet()) {
        if (entry.getValue()) {
          conn = entry.getKey();
          map.put(conn, false);
          break;
        }
      }
      if (conn == null) {
        if (map.size() < maxPoolSize) {
          conn = getNewConnection();
          map.put(conn, false);
        } else {
          wait(waitTime);
          conn = getConnection();
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return conn;
  }
   
  public void releaseConnection(Connection conn) {
    if (conn == null) {
      return;
    }
    try {
      if(map.containsKey(conn)) {
        if (conn.isClosed()) {
          map.remove(conn);
        } else {
          if(!conn.getAutoCommit()) {
            conn.setAutoCommit(true);
          }
          map.put(conn, true);
        }
      } else {
        conn.close();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
}
 
/**
 * 测试类
 */
package com.junones.test;
 
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
public class TestMySQLPool {
  private static volatile int a;
 
  private synchronized static void incr() {
    a++;
  }
 
  public static void main(String[] args) throws InterruptedException {
    int times = 10000;
    long start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      new Thread(new Runnable() {
 
        @Override
        public void run() {
 
          MySQLPool pool = MySQLPool.getInstance();
          Connection conn = pool.getConnection();
          Statement stmt = null;
          ResultSet rs = null;
          try {
            stmt = conn.createStatement();
            rs = stmt.executeQuery("select id, name from t_test");
            while (rs.next()) {
              System.out.println(rs.getInt(1) + ", "
                  + rs.getString(2));
            }
          } catch (SQLException e) {
            e.printStackTrace();
          } finally {
            incr();
            if (rs != null) {
              try {
                rs.close();
              } catch (SQLException e) {
                e.printStackTrace();
              }
            }
            if (stmt != null) {
              try {
                stmt.close();
              } catch (SQLException e) {
              }
            }
            pool.releaseConnection(conn);
          }
        }
      }).start();
    }
    while (true) {
      if (a == times) {
        System.out.println("finished, time:"
            + (System.currentTimeMillis() - start));
        break;
      }
      Thread.sleep(100);
    }
  }
}

测试结果:1万个并发,5秒完成。

以上就是为大家分享的MySQL连接池类,希望大家喜欢,谢谢大家的关注。

延伸 · 阅读

精彩推荐