Welcome!

Weblogic Authors: Yeshim Deniz, Elizabeth White, Michael Meiner, Michael Bushong, Avi Rosenthal

Related Topics: Java IoT, IBM Cloud, Weblogic

Java IoT: Article

Java Feature — Concurrent Queries

A pattern for improving database query performance

Does this sound familiar? You have a domain object, perhaps for reporting purposes, that's built from a ton of JDBC queries and it takes too long to load. Nothing else happens until this object is built, so it's become a bottleneck. Even worse, each of the queries is actually well tuned, so there isn't much to gain from modifying the queries themselves - there are just too many of them. You don't want to change (or can't change) your data model, so what can be done to alleviate this problem short of a major redesign? There are several options like caching, lazy loading, resource pooling. Another worthy option would be to implement a variation of the concurrent query pattern.

Concurrent queries are fairly simple to implement and even simpler to describe. Rather than serializing a set of queries, one after the other, waiting for one to complete before the next begins, one would actually use threads to run sets of independent queries simultaneously. Now, using threading for database I/O might sound daunting or ill-advised, but the Java threads package is one of the best, if not the best, I've had the pleasure of working with. Plus, the new concurrency utilities supplied with Java 5 make using threading for database I/O much more feasible. The UML-ish diagram in Figure 1 attempts to provide a pictorial representation of what I hope to explain in the following paragraphs.

Suppose a domain object is built from 200 queries that can each run from execution to processing results in 100 milliseconds on average. Now 100ms isn't too bad for a query, but stacked end to end, the result would be up to 20 seconds to build an object. Ouch. Now, suppose you could run up to five of these queries concurrently at any one time. In an example that will be described later, I was able to take a similar scenario and increase performance from 20+ seconds to build an object to 5+ seconds. First, though, I'll describe a simpler problem scenario and then implement a solution using concurrent queries, making use of JDBC, connection pooling, and Java 5 thread pools in an effort to demonstrate the type of performance improvements this pattern might render. Later on, I'll cover another, more complicated implementation of an object that's built from several actual database queries. Note: Full source code for these sample implementations is available on sourceforge.net.

A Serialized Baseline Sample Application
First, let's look at the usual case for building objects from database queries. For the following example, a user-defined sleep function was created in a Postgres database (using Postgres magic that I found on the Internet) that could be called as select sleep(N) where N is the number of seconds to sleep. After sleeping for the seconds indicated in the argument the number of seconds slept is returned back as a result. We'll do this with a class called SleepyObject in Listing 1.

This is a fairly standard JDBC query class that selects the sleep(N) function for the number of seconds desired and processes the ResultSet, which simply contains an integer indicating the number of seconds requested to sleep. So, if you "select sleep(1)," the result of that query will be 1. Effectively, the sleep function mimics a query that takes N seconds to complete. In the serialized example (Example1.java), an array of five SleepyObjects is created. Upon creation, each SleepyObject selects the sleep(N) function via JDBC and processes the result. This example creates an array of SleepyObjects then iterates over that array, printing out the return value from the call to the sleep function. Then, the number of seconds it took to execute the entire exercise is printed. Since this sample creates JDBC objects in the usual way, the second SleepyObject isn't created until the first object is fully created (e.g., finished with its sleep(N) query), and so on. So, in this example, since each SleepyObject sleeps 2, 1, 2, 2, and 1 seconds, respectively, the entire application must take at least eight seconds plus overhead to run, as indicated in the output below. This is Example1.java - a serialized example.

package net.sourceforge.concurrentQuery.article.serialized;

import java.sql.SQLException;

public class Example1 {

   public Example1() {}
   public static void main(String[] args) throws SQLException {

     long start = System.currentTimeMillis();

     SleepyObject[] sleepyObjects = { new SleepyObject(2),
          new SleepyObject(1),
          new SleepyObject(2),
          new SleepyObject(2),
          new SleepyObject(1)
          };
     int i = 1;
     for (SleepyObject sleepyObject : sleepyObjects) {
       System.out.println("SleepyObject " + i++ + " returned "
       + sleepyObject.getValue());
     }
     long end = System.currentTimeMillis();
     System.out.println("took: " + new Double(end - start) / 1000 + " seconds");

   }
}

The following is output from Example1.java.

run-example1:
    [java] query is: select sleep(2)
    [java] query is: select sleep(1)
    [java] query is: select sleep(2)
    [java] query is: select sleep(2)
    [java] query is: select sleep(1)
    [java] SleepyObject 1 returned 2
    [java] SleepyObject 2 returned 1
    [java] SleepyObject 3 returned 2
    [java] SleepyObject 4 returned 2
    [java] SleepyObject 5 returned 1
    [java] took: 8.54 seconds

An Implementation Using Concurrent Queries
Next, we'll build on the same example, but this time we'll use a class called ConcurrentSleepyObject to replace SleepyObject. The ConcurrentSleepyObject will use a singleton implementation of the concurrent query pattern to invoke queries and reap the results as seen in Example2.java below.

package net.sourceforge.concurrentQuery.article.concurrent;

import java.sql.SQLException;

public class Example2 {

   public Example2() {}
   public static void main(String[] args) throws SQLException {

     long start = System.currentTimeMillis();

     ConcurrentSleepyObject[] concurrentSleepyObjects = {
          new ConcurrentSleepyObject(2),
          new ConcurrentSleepyObject(1),
          new ConcurrentSleepyObject(2),
          new ConcurrentSleepyObject(2),
          new ConcurrentSleepyObject(1)
          };
     int i = 1;
     for (ConcurrentSleepyObject concurrentSleepyObject :
       concurrentSleepyObjects) {
       System.out.println("ConcurrentSleepyObject " + i++
       + " returned " + concurrentSleepyObject.getValue());
     }
     long end = System.currentTimeMillis();
     System.out.println("took: " + new Double(end - start) / 1000 + " seconds");

   }
}

Both Example1 and Example2 build an array containing five objects, each invokes a database sleep for the same amount of time. However, in this second example, by using an implementation of the concurrent query pattern, the same JDBC calls can be executed in less than half the time (2.86 seconds versus 8.54). This is because we have five queries running at once rather than one at a time. In this example, each of the five queries is run and resolved within its own thread. So, rather than the total execution time being the sum of all queries plus overhead, as in the first example, the total execution time is roughly the amount of time it takes for the longest query to run plus overhead. Here is the output from Example2.java shown below.

run-example2:
    [java] query is: select sleep(2)
    [java] query is: select sleep(1)
    [java] query is: select sleep(2)
    [java] query is: select sleep(2)
    [java] query is: select sleep(1)
    [java] ConcurrentSleepyObject 1 returned 2
    [java] ConcurrentSleepyObject 2 returned 1
    [java] ConcurrentSleepyObject 3 returned 2
    [java] ConcurrentSleepyObject 4 returned 2
    [java] ConcurrentSleepyObject 5 returned 1
    [java] took: 2.86 seconds

To accomplish this, a class called ConcurrentQueryThreadImpl.java was created as a singleton class that encapsulates:

  1. The number of active queries that can run at once (five for purposes of this example).
  2. A ConcurrentHashMap to hold a list of running query threads and a reference to the domain object interface to be used to reap the results of the query. ConcurrentHashMap is a thread-safe HashMap available in the java.util.concurrent package.
  3. A second ConcurrentHashMap to hold a list of queries and domain object interfaces of queries that couldn't be immediately submitted because the maximum number of threads (five) was already running.
  4. The needed JDBC code to execute the queries.
The code fragment in Listing 2 shows the initialization of the ConcurrentQueryThreadImpl class.

The interface CanResolveAConcurrentQuery, referenced in the ConcurrentQueryThreadImpl class, is used in the ConcurrentHashMaps and simply defines two methods that must be implemented by a participant in a concurrent query (e.g., ConcurrentSleepyObject), one to process the SQL results and another (isReaped())method that the ConcurrentQuery implementation can use to indicate to the object that it has processed its SQL results and is ready to go. Below is CanResolveAConcurrentQuery.java.

package net.sourceforge.concurrentQuery.article.concurrent;

import java.sql.ResultSet;
import java.sql.SQLException;

public interface CanResolveAConcurrentQuery {
    boolean processResultSet(ResultSet rs) throws SQLException;
    void setReaped(boolean isReaped);
}

By implementing this interface, the ConcurrentSleepyObject can participate in concurrent queries. Notice that in the getValue() method the query object needs to make sure that it has been "reaped" (e.g., it either processed its results or threw an SQLException) and if not, the object must call the waitForAllQueriesToComplete() method of the ConcurrentQueryThreadImpl singleton, which submits and processes all outstanding queries. See getValue() method of ConcurrentSleepyObject shown in the following.

public class ConcurrentSleepyObject implements CanResolveA-ConcurrentQuery {

...
   public int getValue() throws SQLException {
     if (!reaped) {
       ConcurrentQueryThreadImpl.getInstance().waitForQueriesToComplete();
     }
     return value;
   }
...

This is done so that the object can be sure that its results have been processed before it can be used. The waitForAllQueriesToComplete() method won't return until all running and queued queries are finished. This way, our object can be sure that its results have been processed before continuing. A better option, though, would be to assign a token, or cookie, to each participant in a concurrent query that can be used by the object to ensure that results are ready. This way, if the results aren't ready yet, the object won't have to wait for all the other queries to finish, but could be notified when its query has completed, perhaps moving it to the front of the queue, if necessary. To keep things simple, I opted for the main -strain-and-brute-force approach of waiting for all queries to finish. The complete source for the ConcurrentSleepyObject class is in Listing 3.

Details of the ConcurrentQuery Implementation
As mentioned, this implementation uses two lists to manage queries. The first list is the threads that are currently running SQL queries and can't surpass the configured value for the application. Since each thread corresponds to a JDBC connection, you want to be careful not to set this value too high. I've used five for this example. The second list is the queued queries that haven't been able to run because the running thread list was full when the query was submitted via the runQuery() method. See Listing 4.


More Stories By Andy Pardue

Andy Pardue is a senior software developer who has specialized in the medical software industry for over 15 years, 11 years as a telecommuter from his home office in Mesquite, Texas. He can be reached at: [email protected]

Comments (1) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
JDJ News Desk 12/19/06 01:30:06 PM EST

Does this sound familiar? You have a domain object, perhaps for reporting purposes, that's built from a ton of JDBC queries and it takes too long to load. Nothing else happens until this object is built, so it's become a bottleneck. Even worse, each of the queries is actually well tuned, so there isn't much to gain from modifying the queries themselves - there are just too many of them. You don't want to change (or can't change) your data model, so what can be done to alleviate this problem short of a major redesign? There are several options like caching, lazy loading, resource pooling. Another worthy option would be to implement a variation of the concurrent query pattern.

@ThingsExpo Stories
SYS-CON Events announced today that Yuasa System will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Yuasa System is introducing a multi-purpose endurance testing system for flexible displays, OLED devices, flexible substrates, flat cables, and films in smartphones, wearables, automobiles, and healthcare.
SYS-CON Events announced today that CAST Software will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. CAST was founded more than 25 years ago to make the invisible visible. Built around the idea that even the best analytics on the market still leave blind spots for technical teams looking to deliver better software and prevent outages, CAST provides the software intelligence that matter ...
SYS-CON Events announced today that Daiya Industry will exhibit at the Japanese Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Ruby Development Inc. builds new services in short period of time and provides a continuous support of those services based on Ruby on Rails. For more information, please visit https://github.com/RubyDevInc.
SYS-CON Events announced today that Evatronix will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Evatronix SA offers comprehensive solutions in the design and implementation of electronic systems, in CAD / CAM deployment, and also is a designer and manufacturer of advanced 3D scanners for professional applications.
As businesses evolve, they need technology that is simple to help them succeed today and flexible enough to help them build for tomorrow. Chrome is fit for the workplace of the future — providing a secure, consistent user experience across a range of devices that can be used anywhere. In her session at 21st Cloud Expo, Vidya Nagarajan, a Senior Product Manager at Google, will take a look at various options as to how ChromeOS can be leveraged to interact with people on the devices, and formats th...
SYS-CON Events announced today that Taica will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Taica manufacturers Alpha-GEL brand silicone components and materials, which maintain outstanding performance over a wide temperature range -40C to +200C. For more information, visit http://www.taica.co.jp/english/.
SYS-CON Events announced today that SourceForge has been named “Media Sponsor” of SYS-CON's 21st International Cloud Expo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. SourceForge is the largest, most trusted destination for Open Source Software development, collaboration, discovery and download on the web serving over 32 million viewers, 150 million downloads and over 460,000 active development projects each and every month.
Enterprises have taken advantage of IoT to achieve important revenue and cost advantages. What is less apparent is how incumbent enterprises operating at scale have, following success with IoT, built analytic, operations management and software development capabilities – ranging from autonomous vehicles to manageable robotics installations. They have embraced these capabilities as if they were Silicon Valley startups. As a result, many firms employ new business models that place enormous impor...
SYS-CON Events announced today that TidalScale will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. TidalScale is the leading provider of Software-Defined Servers that bring flexibility to modern data centers by right-sizing servers on the fly to fit any data set or workload. TidalScale’s award-winning inverse hypervisor technology combines multiple commodity servers (including their ass...
As popularity of the smart home is growing and continues to go mainstream, technological factors play a greater role. The IoT protocol houses the interoperability battery consumption, security, and configuration of a smart home device, and it can be difficult for companies to choose the right kind for their product. For both DIY and professionally installed smart homes, developers need to consider each of these elements for their product to be successful in the market and current smart homes.
SYS-CON Events announced today that MIRAI Inc. will exhibit at the Japan External Trade Organization (JETRO) Pavilion at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. MIRAI Inc. are IT consultants from the public sector whose mission is to solve social issues by technology and innovation and to create a meaningful future for people.
In his Opening Keynote at 21st Cloud Expo, John Considine, General Manager of IBM Cloud Infrastructure, will lead you through the exciting evolution of the cloud. He'll look at this major disruption from the perspective of technology, business models, and what this means for enterprises of all sizes. John Considine is General Manager of Cloud Infrastructure Services at IBM. In that role he is responsible for leading IBM’s public cloud infrastructure including strategy, development, and offering ...
As hybrid cloud becomes the de-facto standard mode of operation for most enterprises, new challenges arise on how to efficiently and economically share data across environments. In his session at 21st Cloud Expo, Dr. Allon Cohen, VP of Product at Elastifile, will explore new techniques and best practices that help enterprise IT benefit from the advantages of hybrid cloud environments by enabling data availability for both legacy enterprise and cloud-native mission critical applications. By rev...
SYS-CON Events announced today that Dasher Technologies will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Dasher Technologies, Inc. ® is a premier IT solution provider that delivers expert technical resources along with trusted account executives to architect and deliver complete IT solutions and services to help our clients execute their goals, plans and objectives. Since 1999, we'v...
SYS-CON Events announced today that NetApp has been named “Bronze Sponsor” of SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. NetApp is the data authority for hybrid cloud. NetApp provides a full range of hybrid cloud data services that simplify management of applications and data across cloud and on-premises environments to accelerate digital transformation. Together with their partners, NetApp emp...
SYS-CON Events announced today that TidalScale, a leading provider of systems and services, will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. TidalScale has been involved in shaping the computing landscape. They've designed, developed and deployed some of the most important and successful systems and services in the history of the computing industry - internet, Ethernet, operating s...
Join IBM November 1 at 21st Cloud Expo at the Santa Clara Convention Center in Santa Clara, CA, and learn how IBM Watson can bring cognitive services and AI to intelligent, unmanned systems. Cognitive analysis impacts today’s systems with unparalleled ability that were previously available only to manned, back-end operations. Thanks to cloud processing, IBM Watson can bring cognitive services and AI to intelligent, unmanned systems. Imagine a robot vacuum that becomes your personal assistant tha...
SYS-CON Events announced today that Massive Networks, that helps your business operate seamlessly with fast, reliable, and secure internet and network solutions, has been named "Exhibitor" of SYS-CON's 21st International Cloud Expo ®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. As a premier telecommunications provider, Massive Networks is headquartered out of Louisville, Colorado. With years of experience under their belt, their team of...
Widespread fragmentation is stalling the growth of the IIoT and making it difficult for partners to work together. The number of software platforms, apps, hardware and connectivity standards is creating paralysis among businesses that are afraid of being locked into a solution. EdgeX Foundry is unifying the community around a common IoT edge framework and an ecosystem of interoperable components.
Infoblox delivers Actionable Network Intelligence to enterprise, government, and service provider customers around the world. They are the industry leader in DNS, DHCP, and IP address management, the category known as DDI. We empower thousands of organizations to control and secure their networks from the core-enabling them to increase efficiency and visibility, improve customer service, and meet compliance requirements.