Java并行任务,仅执行一次

时间:2018-07-17 13:22:30

标签: java multithreading parallel-processing

我拥有的这段代码不是并行执行任务, 在这种情况下,它只会执行一次代码(无论在for循环中是什么,但应该为2):

public class mqDirect {
    public static void main(String args[]) throws Exception {
        int parallelism = 2;
        ExecutorService executorService =
                Executors.newFixedThreadPool(parallelism);
        Semaphore semaphore = new Semaphore(parallelism);
        for (int i = 0; i < 1; i++) {
            try {
                semaphore.acquire();
                // snip ... do stuff.. 
                semaphore.release();
            } catch (Throwable throwable) {
                semaphore.release();
            }

            executorService.shutdownNow();
        }
    }
}

3 个答案:

答案 0 :(得分:0)

在Java中,使代码并行工作的主要方法是使用新的Thread作为构造函数参数创建一个Runnable。然后,您需要start

有许多教程可以帮助您正确地进行此操作。

按照您的代码立场,您只是在创建一个ExecutorService(而不使用它),创建一个Semaphore(应该在thread中完成,而不能使用),执行一些过程,然后关闭Executor

顺便说一句:ShutDownNow可能不是您想要的,您应该只使用ShutDown

答案 1 :(得分:0)

  

我拥有的这段代码不会并行执行任务,在这种情况下,它只会执行一次代码(无论在for循环中,但应该为2):

仅仅因为您实例化一个ExecutorService实例并不意味着事物可以神奇地并行运行。除了关闭它之外,实际上您还需要使用该对象。

如果您希望循环中的内容在服务的线程中运行,则需要执行以下操作:

int parallelism = 2;
ExecutorService executorService = Executors.newFixedThreadPool(parallelism);
for (int i = 0; i < parallelism; i++) {
    executorService.submit(() -> {
        // the code you want to be run by the threads in the exector-service
        // ...
    });
}
// once you have submitted all of the jobs, you can shut it down
executorService.shutdown(); 
// you might want to call executorService.awaitTermination(...) here

重要的是要注意,这将在服务中运行您的代码,但不能保证它将“并行”运行。这取决于您的处理器数量和线程固有的竞争条件。例如,第一个任务可能在第二个任务开始之前 启动,运行并完成其代码。这就是设计上异步的线程程序的本质。

但是,如果您至少有2个内核,并且提交的要由executor-service运行的代码需要花费很长时间才能运行,那么很可能它们将在同一时间同时运行。 / p>

最后,正如@OldCurmudgeon指出的那样,您应该在服务上调用shutdown(),该服务允许已提交给该服务的当前作业运行,而shutdownNow()则取消并排队该作业,还调用{ {1}}处理任何正在运行的作业。

希望这会有所帮助。

答案 2 :(得分:0)

好的,所以我找到了这个很好的教程 http://programmingexamples.wikidot.com/threadpoolexecutor

我做了类似

的操作
public class mqDirect {
int poolSize = 2;

int maxPoolSize = 2;

long keepAliveTime = 10;

ThreadPoolExecutor threadPool = null;

final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
        5);

public mqDirect()
{
    threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,
            keepAliveTime, TimeUnit.SECONDS, queue);

}

public void runTask(Runnable task)
{

    threadPool.execute(task);

    System.out.println("Task count.." + queue.size());

}

public void shutDown()
{
    threadPool.shutdown();
}





public static void main (String args[]) throws Exception
{

    mqDirect mtpe = new mqDirect();
    // start first one
    mtpe.runTask(new Runnable()
    {
        public void run()
        {
            for (int i = 0; i < 2; i++)
            {
                try
                {
                    System.out.println("First Task");
                    runMqTests();
                    Thread.sleep(1000);
                } catch (InterruptedException ie)
                {
                }
            }
        }
    });
    // start second one
    /*
     * try{ Thread.sleep(500); }catch(InterruptedException
     * ie){}
     */
    mtpe.runTask(new Runnable()
    {
        public void run()
        {
            for (int i = 0; i < 2; i++)
            {
                try
                {
                    System.out.println("Second Task");
                    runMqTests();
                    Thread.sleep(1000);
                } catch (InterruptedException ie)
                {
                }
            }
        }
    });
    mtpe.shutDown();

   // runMqTests();

}

它有效! 但是问题是,这个重复的代码... runMqtests()是同一任务,是否有一种方法可以指定它在不重复代码的情况下并行运行?

我以此为基础的示例假设每个任务都是不同的。