【问题标题】:JAVA pass a method from outside class to the ThreadPool.submit()JAVA 将一个方法从外部类传递给 ThreadPool.submit()
【发布时间】:2015-12-20 12:27:41
【问题描述】:

我以前没有 JAVA 并发方面的经验,但曾经在 C# 中做过。

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

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

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

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

类工作者

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 });

【问题讨论】:

    标签: java multithreading concurrency


    【解决方案1】:

    你可以传递Runnable本身就是一个参数,

    public void doWork(Runnable runnable) throws IOException, InterruptedException {
    
        while (IsRunning) {
            threadPool.submit(runnable);
    
            Thread.sleep(1000);
        }
    }
    

    Runnable 是一个functional interface,它只有一个方法run,它接受无参数并返回void,因此您可以将它用作函数。

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

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

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

    【讨论】:

    • 所以,如果我需要在那里传递一个 void - 我可以这样做吗? worker.doWork(new Runnable() { myVoid(); });
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2022-01-16
    • 2012-07-07
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多