JAVA将方法从外部类传递到ThreadPool.submit()

标签 java multithreading concurrency

我以前没有 JAVA 并发的经验,但在 C# 中做过同样的事情。

我的任务 创建一个“worker”类,以便在我的应用程序中轻松管理多线程(创建连续线程)。 我想要的结果(使用示例):

Worker worker = new Worker();
worker.threadCount = 10;
worker.doWork(myMethod);
worker.Stop();

能够在我的应用程序的任何类中使用它,接受“void”方法作为“worker.doWork(myMethod);”论证。

我对这个问题的研究做了什么:

worker 类(Class)

package commons.Threading;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

public class Worker {
    static Boolean IsRunning = true;
    public static int threadCount = 2;
    static ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(threadCount);

    public void doWork(**argument method**) throws IOException, InterruptedException {

        while (IsRunning) {
            threadPool.submit(new Runnable() {
                      **argument method**
            });

            Thread.sleep(1000);
        }
    }


    public static void Stop(){
        IsRunning = false;
        threadPool.shutdown(); // Disable new tasks from being submitted
        try {
            // Wait a while for existing tasks to terminate
            if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                threadPool.shutdownNow(); // Cancel currently executing tasks
                // Wait a while for tasks to respond to being cancelled
                if (!threadPool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted
            threadPool.shutdownNow();
            // Preserve interrupt status
            Thread.currentThread().interrupt();
        }
    }
}

ErrorReportingThreadPoolExecutor

package commons.Threading;

import java.util.concurrent.*;

public class ErrorReportingThreadPoolExecutor extends ThreadPoolExecutor {
    public ErrorReportingThreadPoolExecutor(int nThreads) {
        super(nThreads, nThreads,
                0, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());
    }

    @Override
    protected void afterExecute(Runnable task, Throwable thrown) {
        super.afterExecute(task, thrown);

        if (thrown != null) {
            // an unexpected exception happened inside ThreadPoolExecutor
            thrown.printStackTrace();
        }

        if (task instanceof Future<?>) {
            // try getting result
            // if an exception happened in the job, it'll be thrown here
            try {
                Object result = ((Future<?>)task).get();
            } catch (CancellationException e) {
                // the job get canceled (may happen at any state)
                e.printStackTrace();
            } catch (ExecutionException e) {
                // some uncaught exception happened during execution
                e.printStackTrace();
            } catch (InterruptedException e) {
                // current thread is interrupted
                // ignore, just re-throw
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // replace
        // ExecutorService threadPool = Executors.newFixedThreadPool(2);
        // with
        ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(2);

        while (true) {
            threadPool.submit(new Runnable() {
                @Override public void run() {
                    System.out.println("Job is running...");

                    if (Math.random() < 0.5) {
                        int q = 1 / 0;
                    }

                    System.out.println("Job finished.");
                }
            });

            Thread.sleep(1000);
        }
    }
}

所以,问题是 - 我如何从外部类传递“void”方法 threadPool.submit(new Runnable() { here });

最佳答案

你可以传递Runnable本身作为一个参数,

public void doWork(Runnable runnable) throws IOException, InterruptedException {

    while (IsRunning) {
        threadPool.submit(runnable);

        Thread.sleep(1000);
    }
}

Runnable 是一个函数式接口(interface),它有一个方法run,它接受无参数并返回void,因此您可以使用它作为一个函数。

Runnable runnable = new Runnable(){

  public void run(){
   // do work
  }
};
doWork(runnable);

如果你使用的是Java 1.8,可以更简洁地表达

Runnable runnable = ()->{/**do work*/};
doWork(runnable);

关于JAVA将方法从外部类传递到ThreadPool.submit(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34380999/

相关文章:

java - 如何从多模块 Maven 项目构建可执行 jar?

java - 如果我们有足够的处理器来服务所有线程,Thread.yield() 会做任何事情吗?

java - 为什么当 Future 抛出这个 OutOfMemoryError 时没有出现?

java - JFrame 更改边框颜色

java - 休息获取: How to add "URL with Query Parameters" in Query Parameters of a URL?

Java Swing 无法在 mac os 10.15 上显示 FileDialog

java - 以下情况会导致死锁吗?

java - 类级锁定中的静态变量行为

python - 如何在等待 getch 的同时运行副任务?

concurrency - 如何在 Rust 中使用锁?