简体   繁体   English

使用线程同时运行两个独立的任务

[英]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. 我已经在java中学习了很多关于线程的教程,但我找不到答案。

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. 我更喜欢亲自使用ExecutorService

UPDATED with ExecutorService example 使用ExecutorService示例更新

So I wrote this really quick example... 所以我写了这个非常快的例子......

Basically it uses an ExecutorService to run a couple of simple tasks. 基本上它使用ExecutorService来运行几个简单的任务。 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); 现在更改ExecutorService service = Executors.newFixedThreadPool(2); to ExecutorService service = Executors.newFixedThreadPool(1); 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());
                }
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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