A. 2個線程,一個接收,一個存資料庫,前者速度快,感覺只有接收,沒有存儲
放棄存儲線程,把存儲做個一個類(或函數)在接收數據線程里當成功接收到數據時調用存儲類(或函數),或者在接收到數據後在線程里創建存儲線程。
B. C# 多線程 大量數據實時接收\解析\存儲 問題
1、定義兩個線程安全的隊列(System.Collections.Concurrent.ConcurrentQueue<T>)a跟b,其中a用於儲存接受的數據,b用於儲存要持久化的數據。
2、線程A循環讀取數據並儲存到隊列a中。
3、線程B循環從隊列a中讀取數據。
3.1、如果讀取到數據
3.1.1、將解析前的數據跟解析後的數據賦值給專門儲存它們的類c。
3.1.2、將類c添加到隊列b中。
3.1.3、將解析後的數據顯示到UI線程中。
3.2、如果沒有讀取到數據,則sleep一定時間。
4、線程C循環從隊列b中讀取數據。
4.1、如果讀取到數據,則儲存數據。
4.2、如果沒有讀取到數據,則sleep一定時間。
5、線程D可以不要,不過假設數據的處理時間過長,將導致隊列長度不斷增長,所以線程D可以循環判斷隊列a跟隊列b的長度。假設隊列中的對象數量超過特定閥值,則進行一定處理。比如終止程序,比如跳過部分數據,比如停止接收數據等。
C. 如何解決一分鍾內的大量的數據的實時採集
沒見過你所說的程序,這樣的描述沒法提供准確的建議。
一般大量數據的處理,應該寫在線程里,通常不會和採集線程放在一起,應該新開線程。
如果數據處理後是為了顯示,那麼顯示應該是在OnDraw/OnPaint裡面,這里最好使用內存DC做緩沖;如果是直接給控制項,那麼通常可以線程中直接發送給控制項,也可以在定時器裡面獲取數據發送給控制項。
這里要看處理數據的耗時了,如果耗時不多,那麼直接在定時器中定時處理和發送就可以了(比如在OnInitDialog裡面SetTimer(1,1000); 在OnTimer裡面處理即可)
D. java 多線程存儲資料庫
以mysql為資料庫寫的一個粗陋的demo,你參考一下,希望不會因為代碼過多被網路吞了——
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
allotThread();
}
/**
* 將100條數據分成10份並啟動10個線程分別操作
*/
public static void allotThread() {
List<String[]> datas = buildDatas();
for (int i=0; i<100; i+=10) {
List<String[]> tenDatas = datas.subList(i, i + 10);
insertData(tenDatas);
}
}
/**
* 創建100條模擬數據
* @return
*/
public static List<String[]> buildDatas() {
List<String[]> datas = new ArrayList<String[]>();
for (int i=0; i<100; i++) {
String[] data = {"id " + i, "name " + i};
datas.add(data);
}
return datas;
}
/**
* 啟動線程進行數據插入操作
* @param tenDatas
*/
public static void insertData(final List<String[]> tenDatas) {
new Thread(new Runnable() {
public void run() {
String sql = "insert into testtable (id, name) values (?, ?)";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
conn.setAutoCommit(false);
pstmt = getPstmt(conn, sql);
for (String[] data : tenDatas) {
pstmt.setString(1, data[0]);
pstmt.setString(2, data[1]);
pstmt.addBatch();
}
pstmt.executeBatch();
conn.commit();
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
rollback(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
close(pstmt);
close(conn);
}
}
}).start();
}
public static Connection getConnection() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
String dbUrl = "jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(dbUrl, "root", "tooeasy");
return conn;
}
public static PreparedStatement getPstmt(Connection conn, String sql) throws SQLException, ClassNotFoundException {
PreparedStatement pstmt = conn.prepareStatement(sql);
return pstmt;
}
public static void rollback(Connection conn) {
try {
if (null != conn) {
conn.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Connection conn) {
try {
if (null != conn) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(PreparedStatement pstmt) {
try {
if (null != pstmt) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(ResultSet rs) {
try {
if (null != rs) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}