[英]Java concurrent queries
I´m building a benchmarkapplication in Java as experiment. 我正在用Java构建一个基准应用程序作为实验。 The purpose of the tool is to find out how fast a specific database (like Derby, MySQL for example) is in different settings.
该工具的目的是找出特定数据库(例如Derby,MySQL)在不同设置下的运行速度。
At the moment I'm trying to find out how fast a database is when executing multiple queries at the same time. 目前,我正在尝试找出同时执行多个查询时数据库的运行速度。
I thought of creating multiple threads where each thread executes multiple queries. 我想到了创建多个线程,其中每个线程执行多个查询。 But at the moment the queries seems to be executed after the other query is finished instead of concurrently.
但是目前,查询似乎是在另一个查询完成之后而不是并发执行的。
I've got the following (simplified) code: 我有以下(简化)代码:
Runner testCase = new Runner();
for (int i = 0; i < THREAD_COUNT; i++) {
Thread testThread = new Thread(testCase);
testThread.start();
}
public class Runner implements Runnable {
public void run() {
for (int i = 0; i < Benchmarker.QUERY_COUNT; i++) {
stopwatch2.start();
List<Person> selectData = dataHandler.selectData();
stopwatch2.stop();
counter += stopwatch2.getStopwatchValue();
}
}
}
The cpu of mine testsystem has two cores so it should be possible to run two multiple threads at a time, right? 我的testsystem的cpu有两个内核,因此应该可以一次运行两个多线程,对吗?
Somebody an idea how to implement this option? 有人知道如何实现此选项吗?
Thank you for your time and help! 感谢您的时间和帮助!
UPDATE - added selectData method code : UPDATE-添加了selectData方法代码 :
public List<Person> selectData() {
List<Person> data = new ArrayList<Person>();
try {
// Select all persons from the database
ResultSet resultSet = connection.prepareStatement("SELECT * FROM PERSON ORDER BY name").executeQuery();
// Add all the persons to a arraylist
while (resultSet.next()) {
data.add(new Person(resultSet.getString("name")));
}
// Close the resultset
resultSet.close();
} catch (SQLException ex) {
Logger.getLogger(Derby.class.getName()).log(Level.SEVERE, null, ex);
}
return data;
}
There are two problems here: 这里有两个问题:
invokeAll()
or awaitTermination()
that do this for you. invokeAll()
或awaitTermination()
类的方法。 To get an ExecutorService
, use the methods from the Executors
class. ExecutorService
,请使用Executors
类中的方法。 This class also offers methods to wrap Runnable
into Callable
. Runnable
包装为Callable
。 So in the main method you would create an ExecutorService
, submit all the runnables in the for loop, call shutdown()
and awaitTermination()
. ExecutorService
,在for循环中提交所有可运行对象,调用shutdown()
和awaitTermination()
。 Then, print the value of the counter. Runnable
instance uses its own stopwatch, so the stopwatch2
variable needs to be a local variable of run()
. Runnable
实例都使用自己的秒表很重要,因此stopwatch2
变量必须是run()
的局部变量。 Also, the counter
variable cannot be a normal long, but it needs to be an AtomicLong . counter
变量不能为正常的long,但必须为AtomicLong 。 Otherwise the times of some threads could get lost, because normal addition is not an atomic operation (two threads could try to add their times to the counter variable at the same time, which would probably cause a wrong result). Here's the code: 这是代码:
void runTests() {
Runner testCase = new Runner();
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < THREAD_COUNT; i++) {
executor.execute(testCase);
}
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
System.out.println(counter.toString());
}
private AtomicLong counter = new AtomicLong();
public class Runner implements Runnable {
public void run() {
StopWatch stopwatch2 = ... // get a stopwatch instance here
for (int i = 0; i < Benchmarker.QUERY_COUNT; i++) {
stopwatch2.start(); // this needs to reset the stopwatch to 0
List<Person> selectData = dataHandler.selectData();
stopwatch2.stop();
counter.addAndGet(stopwatch2.getStopwatchValue());
}
}
}
If you share the same SQL Connection between the threads then that might be your problem. 如果您在线程之间共享相同的SQL连接,则可能是您的问题。 In general you should avoid sharing the same connection between different threads and use connection pools instead.
通常,应避免在不同线程之间共享相同的连接,而应使用连接池。
The most likely cause of the behaviour you describe is that dataHandler.selectData()
either is synchronized
or relies on a synchronized
method do the work. 您描述的行为的最可能原因是
dataHandler.selectData()
是synchronized
还是依靠synchronized
方法来完成工作。
To solve this, you either need to remove the synchronization (obviously without breaking things), or have a separate dataHandler
per thread (provided the class in question supports that.) 要解决此问题,您要么需要删除同步(显然不会破坏事情),要么每个线程有一个单独的
dataHandler
(前提是所讨论的类支持该处理)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.