JAVA将一个方法从外部类传递给ThreadPool.submit()

时间:2015-12-20 12:27:42

标签: java multithreading concurrency

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

我的任务 创造一个"工人"用于在我的应用程序中管理的简单多线程(创建连续线程)的类。 我想要的结果(用法示例):

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

所以,问题是 - 我如何通过&#39; void&#39;来自外部类的方法threadPool.submit(new Runnable(){ here });

1 个答案:

答案 0 :(得分:1)

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

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

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

        Thread.sleep(1000);
    }
}

Runnable是functional interface,它有一个方法运行,它采用no-param并返回void,因此您可以将其用作函数。

Runnable runnable = new Runnable(){

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

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

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