简体   繁体   中英

Running two independent tasks simultaneously using threads

I've studied lots of tutorials on threads in java but I'm unable to find my answer.

My question is: how to run two independent threads simultaneously?

My case is: I have two tasks;

  1. save some data to the database
  2. send a push notification on a mobile device.

Since these two tasks are independent I want to execute them simultaneously.

I tried using a thread pool with two threads but the problem is that the database tasks finishes quickly but it takes some time to send a push notification.

Consequently when one task is finished while the other is still pending, it throws an exception.

Also there is no problem in my code because it runs fine without using threads.

Thanks in advance

new Thread(new Runnable() {
    public void run() {
        System.out.println("Look ma, no hands");
    }
}).start();

new Thread(new Runnable() {
    public void run() {
        System.out.println("Look at me, look at me...");
    }
}).start();

Works just fine...

I'd prefer the use of an ExecutorService personally.

UPDATED with ExecutorService example

So I wrote this really quick example...

Basically it uses an ExecutorService to run a couple of simple tasks. As it stands, both task will run in parallel with each other (simultaneously)

public static void main(String[] args) throws InterruptedException {
    ExecutorService service = Executors.newFixedThreadPool(2);
    service.submit(new PathScanner());
    service.submit(new Counter());

    service.shutdown();
    service.awaitTermination(1, TimeUnit.DAYS);

    System.exit(0);
}

public static class PathScanner implements Callable<Object> {

    @Override
    public Object call() throws Exception {
        scan(new File("C:/"), 0);
        return null;
    }

    protected void scan(File path, int deepth) {
        if (deepth < 15) {
            System.out.println("Scanning " + path + " at a deepth of " + deepth);

            File[] files = path.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    scan(file, ++deepth);
                }
            }
        }
    }
}

public static class Counter implements Callable<Object> {

    @Override
    public Object call() throws Exception {
        for (int index = 0; index < 1000; index++) {
            Thread.sleep(1);
            System.out.println(index);
        }
        return null;
    }
}

Run it...

Now change ExecutorService service = Executors.newFixedThreadPool(2); to ExecutorService service = Executors.newFixedThreadPool(1); and run it again. Did you see the difference?

This is the way to control the number of simultaneously threads that executor can use while processing it's queue.

Make up some more tasks and add them to the queue and see what you get.

I was having a use case to search file in multiple folders using multithreading. As an input, I was having only root directory path and there can be any number of child directories. Assumption - File will always be available only in one of the child directories.

import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SearchFile implements Runnable {

    private String dirPath = null;

    public SearchFile() {

    }

    public SearchFile(String dirPath) {
        this.dirPath = dirPath;
    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        File dir = new File("D://");
        checkRootDirectory(dir);
        long endTime = System.currentTimeMillis();
        System.out.println("Time taken: "+(endTime - startTime) + "ms");
    }

    private static void checkRootDirectory(File root) {
        File[] list = root.listFiles(new FileFilter() {

            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory() && !pathname.isHidden();
            }
        });

        ExecutorService service = Executors.newFixedThreadPool(list.length);
        for (File directories : list) {
            String dirPath = directories.getAbsolutePath();
            Thread thread = new Thread(new SearchFile(dirPath));
            service.execute(thread);
        }
        service.shutdown();
        while(!service.isTerminated()) {

        }
    }

    @Override
    public void run() {
        checkEachDirectory(new File(dirPath), "Temp.txt");
    }

    private void checkEachDirectory(File root, String fileName) {
        File[] list = root.listFiles();
        if (null != list) {
            for (File dir : list) {
                if (dir.isDirectory()) {
                    checkEachDirectory(dir, fileName);
                } else if (fileName.equalsIgnoreCase(dir.getName())) {
                    System.out.println(
                            "Thread name: " + Thread.currentThread().getName() + " Founded @" + dir.getAbsolutePath());
                }
            }
        }
    }
}

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