【问题标题】:how to do Multi-threaded processing in sequence?如何按顺序进行多线程处理?
【发布时间】:2013-09-10 17:24:41
【问题描述】:

这是我要解决的问题,但不确定如何解决:我有一个对象数组(例如大小为 100),每个对象都有一些 id。

Class Employee{
   int EmployeeId;
}

有 10 个线程将从这个数组中读取数据并插入 进入数据库。

如何确保数据按照EmployeeId的递增顺序插入到DB中。 例如:

如果数组中有 EmployeeID 为 6、8 和 4 的对象,则这些对象 应按 EmployeeID 4、6 和 8 在 DB 中的顺序插入 DB。 如何为此编写多线程代码?

更新:请忽略 DB 部分,如果它令人困惑,我的主要意图是同时处理但顺序。

【问题讨论】:

  • 如果数据库不控制 id 生成,按特定顺序输入它们有什么区别?
  • 通常很难(不可能?)提前知道线程将被执行的顺序。所以我猜你不能确保你的对象是按顺序添加的,如果它们是由不同的线程竞赛添加的。但是你可以实现信号量来锁定一个线程并等待其他线程将它们的对象添加到数据库中。
  • 如果你想要一个定义的序列,只需使用一个线程。多线程用于并发、独立的任务。

标签: java multithreading concurrency


【解决方案1】:

我认为您不了解这里使用线程。 Threading1 适用于并行任务,其中(可能除了一些障碍)排序无关紧要,您的线程并行运行。你想要一个简单的循环或其他类型的串行行为。

你可以用一个线程轻松地做到这一点。你可以在这里走安全的道路。线程不保证任何关于优化和排序的事情。如果预处理很昂贵,请以线程方式进行,然后确保线程全部以CountdownLatch 结束,然后插入数据库。

1穿线​​可导致死亡、窒息、寒战、发烧、溺水、感染、恶心和the inability to control heavy machinery

【讨论】:

  • 如果每个项目的处理量很大,并且订单仅在返回结果时才重要,那么并行性仍然有意义。在这种情况下,可能会(ab)使用倒计时闩锁之类的东西。
  • @jpm *ab*​已使用。最好还是先线程处理,再串行部分完成。
  • @jpm 您仍然会受到数据库速度的限制。
  • 对,这完全取决于对于这个问题来说,处理成本还是 IO 成本更高。 (提示:通常是 IO)
  • @hexafraction 如果我们忽略所有含义,只想在多线程中按顺序处理所有这些对象怎么办?
【解决方案2】:

如果我理解正确,对于数组的每个条目,您有一些任务必须按顺序执行(我假设是 10 个)。

首先,你需要在一个实现Runnable的类中按顺序组织这10个任务:

public class ThreadedTask implements Runnable {
    private Employee employee;
    public ThreadedWork(Employee employee) {
        this.employee = employee;
    }
    public void executeTaskList(Employee employee) {
        task1(employee);
        task2(employee);
        // ...
        task10(employee);
    }
    public void run() {
        executeTaskList();
        notify();
    }
}

然后,您可以实施以下解决方案之一:

  1. 在数组中插入Employee对象,创建ThreadedTask对象并在线程上调用它的执行。
  2. 在数组中插入所有Employee对象,然后使用for循环创建ThreadedTask对象并在线程上调用它的执行。

我将在这里为选项 2 写一个简单的建议:

/*
 * I am assuming that there`s an array called empArray, which holds 100 employees.
 * It's up to you to decide how it is populated.
 */
public void processEmployees() {
    // ...
    for(Employee e : empArray) {
        (new Thread(new ThreadedTask(e))).start()
    }
    // ...
}

如您所见,逻辑分为两部分:由您定义填充empArray 的方式,以及如何创建和执行ThreadedTask 对象。但是ThreadedTask 为每个Employee 对象按顺序 执行任务列表。

请注意,无法判断在任何给定时刻处理了哪个Employee 对象。所有员工都是并发处理的,但每个员工的任务是按顺序执行的。

希望对你有帮助

【讨论】:

  • 你说得对,我也在考虑将所有对象放在优先级为 EmployeeID 的 PriorityBlockingQueue 中,然后将该队列传递给一个任务并启动 10 个线程并让该任务执行。但我再次被问到所有线程都会按顺序选择任务,但不确定它是否会按顺序完成。 (我在一次采访中被问到这个问题)。由于无法解决它,我被告知解决如何确保不同的线程没有从输入中选择相同的记录。 :(
  • 您必须隔离任务。在我提出的解决方案中,每个Runnable 对象都与一个(并且只有一个)Employee 对象相关,因此一个线程没有机会与另一个Employee 一起工作。
  • @Barranka - 我想你已经在这里回答了我的一个问题。可以肯定的是,我需要使用六个线程对包含 45 个元素的列表中的每个元素执行繁重的数学运算,但完成后,列表的顺序必须相同。你的回答适用于我的情况吗?或者现在有更好的 Java 版本吗?
  • @MissLucy 感谢您阅读我的帖子。我认为最好将您的评论作为一个新问题发布(如果您认为这篇文章很有用,请考虑添加一个链接)。一定要包含一些示例代码来看看你在做什么(记得阅读"Help Center: How to create a Minimal, Complete and Verifiable Example"
猜你喜欢
  • 2019-02-27
  • 1970-01-01
  • 2017-01-02
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多