Abhay
Abhay

Reputation: 139

Multithreading to improve performance

I have a database table requests_pending which contains requests(messages) from user to be processed. The rate of incoming request is 1000/second. After a request has been processed it is deleted from requests_pending table and inserted in requests_processed. And response for each request is inserted into table response, which is then sent to user. In order to keep up with the incoming requests I tried using multiple threads to fetch and process request. I have used synchronized BLOCK on request fetching so that only one thread access the table at a time and hence avoid duplicate processing of requests.

    synchronized (this) {
      fetch request...
    }
    processRequest();

But synchronized block is slowing down the application. Single Thread is performing better than multiple Threads, I guess because there is no synchronization overhead. Any alternate approach to improve performance.

Upvotes: 0

Views: 133

Answers (2)

AnatolyG
AnatolyG

Reputation: 1587

As people said, your story looks like a story of asynchronous execution which really can be implemented using a standard JMS container, for example. But if you'd like to insist on your own solution:

  1. Try to decrease contention. Use lock on User object to fetch and process its requests instead of lock on a processor.

  2. Use SELECT FOR UPDATE if your DBMS supports it to lock a user in "user" table before a request of this user is being processed. This moves synchronization from java code to DB level and still has significant cost.

  3. Or try to rid off the locks at all. Share user data among N threads when each thread processes data for a given subset of users. Let's say, the first thread processes requests of users A-F, second one for users G-L etc. Use any reasonable static/dynamic rule. Also, since JDBC connection isn't thread-safe, each thread should establish and hold its own instance of connection. As result, you don't have a critical section at all, since you don't have any data shared among any threads and this may work even faster than an "out of the box" JMS setup, since you manage all the process and you don't have any "generic" code.

And finally, check your JDBC code, please: make sure you use PreparedStatement, batch processing and appropriate isolation level for transactions.

Upvotes: 0

maaartinus
maaartinus

Reputation: 46422

Single Thread is performing better than multiple Threads, I guess because there is no synchronization overhead.

This sentence makes little sense to me, but the synchronization overhead is surely irrelevant at the rate of 1000 per second.

As Marko Topolnik already wrote, dedicated threads solve the problem nicely. Let a single thread fetch all requests to be processed, submit them all to a Executor, remove them. If no requests were found, just sleep for a while.

Inserting can be done by each worker thread or you may want do dedicate another thread for it (polling a queue).

Upvotes: 1

Related Questions