user2248702
user2248702

Reputation: 2998

Get response from MySQL multithreading Java

Let's say, for example I have a large, time consuming processing task which often needs to query a MySQL database. I want the main thread to keep processing when waiting for the response from the SQL server so I make the query in another thread.

How would I go about getting the response data from the query if it is in another thread? I could probably save the result in an array or a queue but I'm not sure what the best practice is when dealing with MySQL queries in a separate thread (using connection pool.)

Thanks.

Upvotes: 1

Views: 197

Answers (2)

vanOekel
vanOekel

Reputation: 6538

You can use another thread (or runnable) to get query results, but make sure that the query-task is self-contained: it opens a connection (or gets one from the conneciton pool), fires the query, gets the results, stores the results in some variable (e.g. HashMap), closes the query, the result-set and the connection (or returns it to the pool). When all this is done (with appropriate try-catch-finally blocks), the task can then 'send' the data to the main processing thread.

Using the method described in the answer by TeresaCarrigan, following an example how a "worker thread" can 'send' data to the "main thread":

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Q21176667 implements Runnable {

    private static volatile boolean stop;

    public static void main(String... args) {

        Thread t = new Thread(new Q21176667());
        t.start();
        sleep(200);
        stop = true;
    }

    private BlockingQueue<Long> q = new ArrayBlockingQueue<Long>(100); 

    @Override
    public void run() {

        try {
            while (!stop) {
                if (q.peek() == null) {
                    new Thread(new GetUpdates(this)).start();
                }
                long l = q.take();
                System.out.println("Main sleep: " + l);
                sleep(l);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void add(Collection<Long> moreData) {

        for (Long l : moreData) {
            q.add(l);
        }
    }

    static class GetUpdates implements Runnable {

        final Q21176667 processor;

        public GetUpdates(Q21176667 processor) {
            this.processor = processor;
        }

        @Override
        public void run() {

            List<Long> vlist = new ArrayList<Long>();
            // Run query, process results
            sleep(10);
            Random r = new Random();
            for (int i = 0; i < 3; i++) {
                vlist.add(new Long(r.nextInt(10)));
            }
            System.out.println("Adding " + vlist.size() + " more sleeps.");
            processor.add(vlist);
        }
    }

    public static void sleep(long timeMs) { 
        try { Thread.sleep(timeMs); } catch (Exception ignored) {}
    }

}

Output looks like:

Adding 3 more sleeps.
Main sleep: 5
Main sleep: 9
Main sleep: 0
Adding 3 more sleeps.
Main sleep: 3
Main sleep: 7
Main sleep: 8
etc.

Upvotes: 1

Teresa Carrigan
Teresa Carrigan

Reputation: 698

One way is to have the class that creates the thread pass in "this" to the constructor of the class that runs the thread, and when the thread finishes getting the results, it can call a public method on the first class to pass the results back. If this doesn't make enough sense, I can provide code snippets.

Upvotes: 0

Related Questions