使两个线程处理独立,无需sleep / wait / notify

时间:2017-02-18 11:11:27

标签: java multithreading thread-safety

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

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

问题:

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

需要解决方案:

即使 下载 线程处理时间超过1分钟,到那时我应该调用 writefile 15次(15 * 4secs)。 (等待或睡眠方法会延迟我的过程,因为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();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这里有几点。

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

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

  3. 正如所指出的那样,您并没有以线程安全的方式处理数据结构。不确定为什么你要通过列表下载,因为它有一个全局静态实例。

  4. 你得到了你想要的东西,我做了以下事情:

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

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

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

    4. 因此,整体算法是启动一个监视器线程,启动一个管理线程池以进行下载的工作委托线程,让监视器线程接收要下载的新文件或一组文件。仅将锁定共享数据的时间足以更新待处理列表。让下载管理器线程锁定的时间足够长,以便在工作人员可用时拉下一个作业。