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