2

I'm working on a Java-based server in which I will have multiple threads (one thread for each connected user + some extra). There will be some database connection involved, so I was thinking that each time the server makes a SELECT query to the database it will start a new thread for this, to prevent blocking from the current thread. I'm planning on using a connection pool for this and I think I know how to do that. (I've looked into C3P0) However, there will be a lot of UPDATE statements involved also, but it's not important that these are ran directly, it's ok with a delay here. And since there might be a lot of UPDATE statements, I'm thinking of having a single worker thread for all UPDATE statements. As I see it, this will have the advantage of being able to re-use PreparedStatement-objects

The question: How can I, from the other threads, tell the UPDATE-worker thread to run some statements? I know about multithreading and how to make threads "talk" to each other using synchronized blocks, but with the database involved it suddenly feels more complex. I have read that prepared statements and connections should not be shared between threads.

The idea I have right now on how to solve it: (doesn't feel like a good solution)

Use a LinkedBlockingQueue (or another kind of Queue) of a custom class with information about which kind of UPDATE statement to call and which parameters to send it. And then the worker thread will read from this queue when it's notified (which it will be when something is added to the queue) and there it will run the appropriate method which will use the appropriate prepared statement, set the params, and call it.

Edit: A bad think that I see myself with this approach is that the params might be ints, String, double, or whatever. How to store them in the custom class? Doesn't feel good to store them all as String.

Am I on the right track here or is there a better way to solve this?

Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
  • 1
    You don't need a notification process - just calling `queue.poll(timeout, timeunit)` will block until something gets added to the queue. – assylias Oct 30 '12 at 18:42
  • @assylias Thanks, that will make it a little easier. Do you think I'm on the right track by using a queue to do this? – Simon Forsberg Oct 30 '12 at 18:48
  • Hum... Ignore my previous comment: you can call `queue.take()` which will block until something is on the queue. Your approach makes sense - you have a thread that calls `queue.take` to wait until a query is put on the queue, executes it and go back to `queue.take()`. – assylias Oct 30 '12 at 18:50
  • @assylias Do you know of a better way to store the params for each item in the queue? All I can think of is to store them as String, or Object (and then check if it's Integer, Double, String...) – Simon Forsberg Oct 30 '12 at 19:01

1 Answers1

3

No need for an explicit blocking queue. You can have a worker thread and a work queue encapsulated by an ExecutorService. As for the values, you can use generics:

class ThreadTask<T> implements Runnable {
    private T value;

    public ThreadTask(T value) {
        this.value = value;
    }

    public void run() {
        // update based on value
    }
}

...

ExecutorService exec = Executors.newSingleThreadExecutor();
exec.submit(new ThreadTask<String>("asdf"));
exec.submit(new ThreadTask<Integer>(1));

The single thread executor is simply a worker thread waiting on a queue and executing the submitted tasks in order. No need for other explicit management.

Tudor
  • 61,523
  • 12
  • 102
  • 142