简体   繁体   中英

How to call a method using multiple threads instead of sequentially

I have a process method in two of my classes which accepts a Map of String.

In the below code, I am using a for loop which will call the process method in two of my classes one by one (sequentially) which is fine.

for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
    final Map<String, String> response = entry.getPlugin().process(outputs);

    System.out.println(response);
}

But is there any way I can launch two thread for this? One thread will call process method of one of my class and second thread will call process method in my second class? And then after getting response from each thread, I want to write to the database. meaning each thread will write to database.

And also there should be timeout feature as well for each thread. We will wait for each thread a specified amount of time, meaning if one of the process method is not returned withing a certain time, then it will get timedout.

Is this possible to do in my use case? If yes, can anyone provide me an example of how to do this? Thanks.

Any help will be appreciated on this.

You can create an ExecutorService with however many threads allocated as you want running, eg

ExecutorService executor = Executors.newFixedThreadPool(2)

Now inside of your for loop you would do something like

for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
    executor.submit(new Runnable () {
        public void run() {
            final Map<String, String> response = entry.getPlugin().process(outputs);
            // write to database
            System.out.println(response);
        }
    }
}

You may also want to have a separate thread handling all of the database writes - your runnables would send their results to it via a BlockingQueue or something along those lines

// Three threads: one thread for the database writer, two threads for the plugin processors
final ExecutorService executor = Executors.newFixedThreadPool(3);

final BlockingQueue<Map<String, String>> queue = new LikedBlockingQueue<>();

Future future = executor.submit(new Runnable () {
    public void run() {
        Map<String, String> map;
        try {
            while(true) {
                // blocks until a map is available in the queue, or until interrupted
                map = queue.take();
                // write map to database
            }
        } catch (InterruptedException ex) {
            // IF we're catching InterruptedException then this means that future.cancel(true)
            // was called, which means that the plugin processors are finished;
            // process the rest of the queue and then exit
            while((map = queue.poll()) != null) {
                // write map to database
            }
        }
    }
}

for (ModuleRegistration.ModulesHolderEntry entry : ModuleRegistration.getInstance()) {
    executor.submit(new Runnable () {
        public void run() {
            final Map<String, String> response = entry.getPlugin().process(outputs);
            // put the response map in the queue for the database to read
            queue.offer(response);
        }
    }
}

// this interrupts the database thread, which sends it into its catch block
// where it processes the rest of the queue and exits
future.cancel(true); // interrupt database thread

// wait for the threads to finish
executor.awaitTermination(5, TimeUnit.MINUTES);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM