当前位置: 首页 > 知识库问答 >
问题:

Java并发任务实现

连昊天
2023-03-14

我的问题是这样的:我最多可以运行三个并发任务。这些任务可以同时处理1到100个作业。我有很多线程不断地提交单个作业,我想尽可能快地响应它们。在一个任务中处理100个作业所花费的时间与在一个任务中处理1个作业所花费的时间相同。作业随机间隔出现。提交作业的线程需要阻塞,直到作业完成,或者遇到超时。快速响应提交作业的线程是这里的驱动程序。

所以我目前的逻辑是:如果有

我只是不太确定在Java中设置它的最佳方式。我创建了一个简单的信号量版本,它运行良好,但没有利用同时提交作业的能力。我应该如何最好地扩展它以完全满足我的要求?(没有使用信号量的要求,这只是我到目前为止拥有的)。

private static final Semaphore semaphore = new Semaphore(3);

public static Response doJob(Job job) throws Exception
{ 
    final boolean tryAcquire = this.semaphore.tryAcquire(this.maxWaitTime, TimeUnit.MILLISECONDS);

    if (tryAcquire)
    {
        try
        {
            return doJobInNewTask(job); // we'd actually like to do all the jobs which are queued up waiting for the semaphore (if there are any)
        }
        finally
        {
            this.semaphore.release()
        }       
    }
}

共有1个答案

谷梁波
2023-03-14

您可以将Executor服务与固定大小的线程池一起使用:

class ExecutorExample {
    private final static ExecutorService executorService;
    private final static long maxWaitTime = 5000;

    static {
        executorService = Executors.newFixedThreadPool(3);
    }

    private static class Response {}
    private static class Job {}

    public static Response doJob(final Job job) throws Exception {
        final Future<Response> future = executorService.submit(
            new Callable<Response>() {
                @Override
                public Response call() throws Exception {
                    return doJobInNewTask(job);
                }
            }
        );
        try {
            // get() blocks until the task finishes.
            return future.get(maxWaitTime, TimeUnit.MILLISECONDS);
        }
        catch (final TimeoutException e) {
            // we timed out, so *try* to cancel the task (may be too late)
            future.cancel(/*mayInterruptIfRunning:*/false);
            throw e;
        }
    }

    private static Response doJobInNewTask(final Job job) {
        try { Thread.sleep(maxWaitTime / 2); }
        catch (final InterruptedException ignored) {}
        return new Response();
    }

    public static void main(final String[] args) {
        final List<Thread> threads = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            final Thread t = new Thread() {
                @Override
                public void run() {
                    try {
                        System.out.println(doJob(new Job()));
                    }
                    catch (final Exception e) {
                        System.out.println(e.getClass().getSimpleName());
                    }
                }
            };
            threads.add(t);
            t.start();
        }

        for (final Thread thread : threads) {
            try { thread.join(); }
            catch (final InterruptedException ignored) {}
        }

        System.out.println("Done!");
    }
}

输出:

ExecutorExample$Response@1fe4169
ExecutorExample$Response@9fdee
ExecutorExample$Response@15b123b
ExecutorExample$Response@bbfa5c
ExecutorExample$Response@10d95cd
ExecutorExample$Response@131de9b
TimeoutException
TimeoutException
TimeoutException
TimeoutException
Done!

这里的一个潜在问题是取消。由于日程安排已超出您的控制范围,因此有可能在您等待任务超时后,但在cancel()有机会完成任务之前,启动任务。结果不会传播,但如果任务有有意义的副作用,这种方法可能会产生问题。

 类似资料:
  • 本文向大家介绍ember.js 并发任务,包括了ember.js 并发任务的使用技巧和注意事项,需要的朋友参考一下 示例 另一种事实上的社区标准是称为ember-concurrency的附加组件,它使很多承诺混乱都消除了。 可以使用命令安装ember install ember-concurrency。 优点 复杂异步代码的直观推理。 提供用于管理任务的完整API。 可以取消。 可以直接在组件中使

  • 假设我有几个任务要在Java中并行运行。每个任务要么返回成功,要么返回失败。每个任务都有一个相关的截止日期。如果任务未在截止日期前完成,它将被中断(所有任务都可中断)并返回失败。 如果其中一个任务失败(即返回失败),我们将中断所有仍在运行的其他任务。 我们应该等到所有任务都完成,最后如果所有任务都返回成功,则返回成功;如果至少有一个任务返回失败,则返回失败。 你将如何实施它?我将使用util。同时

  • 我是JavaFx/并发的新手,所以我在JavaFX中阅读了并发教程,但是我仍然对JavaFX Gui中后台线程的实现有点困惑。 我试图编写一个与一些串行设备(使用JSSC-2.8)接口的小图形用户界面,并根据这些设备的响应更新图形用户界面。但是,在写入消息和设备响应之间有一个延迟,在任意的时间内使用Thread.sleep()对我来说不是一个可靠的编程方式。因此,我想使用并发包中的等待()和通知(

  • 使用map()和一个基本的线程池 # futures_thread_pool_map.py from concurrent import futures import threading import time def task(n): print('{}: sleeping {}'.format( threading.current_thread().name,

  • 我试着用一个实例并行运行许多计划任务,每一个我这样配置任务 但是有很多实例每秒开始,而第一个实例尚未完成。是否可以同时配置任务运行的一个实例?我的豆子配置在Spring调度器.xml

  • 由于引用字段lastLogin没有任何字段的属性来保证可见性(final、volatile、guarded或由静态初始化器初始化),我认为映射本身可能不会以完全构造的状态显示给其他线程,因此本末倒置。还是我错过了什么?