Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java并发查询_Java_Multithreading_Concurrency_Benchmarking - Fatal编程技术网

Java并发查询

Java并发查询,java,multithreading,concurrency,benchmarking,Java,Multithreading,Concurrency,Benchmarking,我正在用Java构建一个基准应用程序作为实验。该工具的目的是了解特定数据库(例如Derby、MySQL)在不同设置下的速度 目前,我正试图找出一个数据库在同时执行多个查询时的速度 我想创建多个线程,每个线程执行多个查询。但目前,查询似乎是在另一个查询完成后执行的,而不是并发执行的 我有以下(简化的)代码: Runner testCase=newrunner(); 对于(int i=0;i

我正在用Java构建一个基准应用程序作为实验。该工具的目的是了解特定数据库(例如Derby、MySQL)在不同设置下的速度

目前,我正试图找出一个数据库在同时执行多个查询时的速度

我想创建多个线程,每个线程执行多个查询。但目前,查询似乎是在另一个查询完成后执行的,而不是并发执行的

我有以下(简化的)代码:

Runner testCase=newrunner();
对于(int i=0;i
我的测试系统的cpu有两个核心,所以一次应该可以运行两个多线程,对吗

有人想知道如何实现这个选项吗

谢谢你的时间和帮助

更新-添加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;
}
public List selectData(){
列表数据=新的ArrayList();
试一试{
//从数据库中选择所有人员
ResultSet ResultSet=connection.prepareStatement(“按姓名从个人订单中选择*).executeQuery();
//将所有人员添加到arraylist
while(resultSet.next()){
add(新的Person(resultSet.getString(“name”));
}
//关闭结果集
resultSet.close();
}catch(SQLException-ex){
Logger.getLogger(Derby.class.getName()).log(Level.SEVERE,null,ex);
}
返回数据;
}

您描述的行为最可能的原因是
dataHandler.selectData()
要么是
同步的
,要么依赖
同步的
方法来完成工作


要解决这个问题,您需要删除同步(显然不会破坏同步),或者每个线程有一个单独的
dataHandler
(前提是相关类支持它)。

您描述的行为最可能的原因是
dataHandler.selectData()
要么是
同步的
要么依靠
同步的
方法来完成工作


要解决这个问题,您需要删除同步(显然不会破坏同步),或者每个线程都有一个单独的
数据处理程序
(前提是所讨论的类支持该类)。

如果线程之间共享相同的SQL连接,那么这可能是您的问题。一般来说,您应该避免在不同线程之间共享相同的连接,而是使用连接池。

如果在线程之间共享相同的SQL连接,那么这可能是您的问题。一般来说,您应该避免在不同线程之间共享同一连接,而是使用连接池。

这里有两个问题:

  • 您必须等待所有线程完成。这可以手动完成,但不使用线程要容易得多,但它提供了一种方法,如
    invokeAll()
    waittermination()
    ,可以为您执行此操作。要获取
    执行器服务
    ,请使用
    执行器
    类中的方法。此类还提供了将
    Runnable
    包装为
    Callable
    的方法。因此,在main方法中,您将创建一个
    ExecutorService
    ,提交for循环中的所有可运行项,调用
    shutdown()
    waittermination()
    。然后,打印计数器的值
  • 你必须注意正确添加时间。为此,每个
    Runnable
    实例使用自己的秒表非常重要,因此
    stopwatch2
    变量需要是
    run()
    的局部变量。另外,
    计数器
    变量不能是正常的long,但必须是一个。否则,某些线程的时间可能会丢失,因为正常加法不是原子操作(两个线程可能会同时尝试将其时间添加到计数器变量,这可能会导致错误的结果)
  • 代码如下:

    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());
    
           }
        }
    }
    
    void runTests(){
    Runner testCase=新的Runner();
    ExecutorService executor=Executors.newCachedThreadPool();
    对于(int i=0;i
    这里有两个问题:

  • 您必须等待所有线程完成。这可以手动完成,但不使用线程要容易得多,但它提供了一种方法,如
    invokeAll()
    waittermination()
    ,可以为您执行此操作。要获取
    执行器服务
    ,请使用
    执行器
    类中的方法。此类还提供了将
    Runnable
    包装为
    Callable
    的方法。因此,在main方法中,您将创建一个
    ExecutorService
    ,提交for循环中的所有可运行项,调用
    shutdown()
    waittermination()
    。然后,打印计数器的值
  • 你必须注意正确添加时间。为此,重要的是每个
    Runnable
    实例使用自己的秒表,因此
    停止
    
    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());
    
           }
        }
    }