【问题标题】:make two threads process independent without sleep/wait/notify使两个线程独立处理而无需睡眠/等待/通知
【发布时间】:2017-02-18 11:11:26
【问题描述】:

我正在运行两个线程,其中一个线程是读取 Feed 并将元素放入全局变量中,另一个线程用于从全局变量中获取信息,它将开始下载文件。

writefile 线程的处理时间仅需毫秒,download 线程的处理时间可能需要最多超过 40 秒,因为它取决于文件。

问题:

writefile 线程必须每 4 秒运行一次,因为我不会错过每秒提供信息的 Feed,但如果我运行以下程序,writefile 线程在 download 线程完成其进程之前根本不会执行。

需要解决方案:

即使 download 线程处理时间超过 1 分钟,我也应该调用 writefile 15 次(15*4 秒)。 (等待或睡眠方法会延迟我的进程,因为 Feed 在短短几个小时内就为我提供了数千个文件)

请浏览下面的代码。请编辑和分享知识。

提前致谢

  public class Upload {
    static List<DTOs> list = new ArrayList<E>();
    String date = "";
    Map<String, DTO> map = new HashMap<String, DTO>();

    public static void main(String[] args) {
        while (true) {
            Thread writefile = new Thread() {
                public void run() {
                    write();
                    // map collection is being used in download thread and also
                    // list
                }
            };

            Thread download = new Thread() {
                public void run() {
                    downloadProcess(list, date);
                }
            };

            writefile.start();
            download.start();

            try {
                writefile.join();
                download.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

【问题讨论】:

  • 你的集合不是线程安全的,你的线程只运行一次,不清楚为什么你有多个线程,因为你说一个运行得很快,而另一个花费大部分时间等待网络。
  • @PeterLawrey 一个线程正在读取提要,与另一个线程相比,它的速度更快。我正在 while 循环中启动两个线程。
  • 我明白了,但它并没有解决我的观点,即您为什么要这样做或为什么集合不是线程安全的。提示:它更复杂,但不保证更快。
  • 我真正的问题是两个线程应该独立工作,一个不应该等待另一个执行它的进程,你问的是我正在使用的变量,但这不是我真正关心的问题
  • 很难知道该建议您做什么,因为它一开始似乎没有意义。线程同时运行,但没有线程安全,无法保证一个线程何时/是否会看到另一个线程的更新。

标签: java multithreading thread-safety


【解决方案1】:

这里有几点。

  1. 您的代码没有异步运行,因为您在每个循环结束时加入了线程。这意味着主线程每次都必须等待其他线程完成。

  2. 没有理由每次都重新创建线程。这是浪费的开销。

  3. 正如所指出的,您似乎并没有以线程安全的方式处理数据结构。不知道你为什么要传递列表来下载,因为它有一个全局静态实例。

你得到你想要的,我会做以下事情:

  1. 启动一个线程来进行提要监控。让它在线程内循环。

  2. 使用线程工作池进行下载。没有理由不一次运行多个下载,但您可能确实想限制总数。

  3. 确保您锁定了对共享数据结构的访问。应该这样做,以便访问非常快,因此两个线程都不会长时间阻塞。

所以总体算法是启动一个监控线程,启动一个管理下载线程池的工作委派线程,让监控线程接收一个新文件或一组文件来下载。将您的共享数据锁定足够长的时间以更新待处理列表。让下载管理器线程锁定足够长的时间,以便在工作人员可用时拉下一个作业。

【讨论】:

    猜你喜欢
    • 2013-05-29
    • 2014-07-17
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多