【问题标题】:Threads not getting stored in sequence in set线程未按顺序存储在集合中
【发布时间】:2023-03-08 23:30:01
【问题描述】:

我正在尝试将 10 个线程添加到一个集合中并按顺序命名它们。但是当我调试查看集合时,线程不是按顺序存储的。谁能告诉我我做错了什么?

 Set<Thread> allThreads = new HashSet<Thread>();
        final DemoClass demo = new DemoClass();
    

        for (int i = 0; i < 10; i++) {

            Thread thread = new Thread(new Runnable() {
                public void run() {
                    try {
                        demo.getName();
                    } catch (InterruptedException ie) {
                        System.out.println("We have a problem");
                    }
                }
            });
            thread.setName("Thread_" + (i + 1));
            allThreads.add(thread);
        }

        for (Thread t : allThreads) {
            t.start();
        }

        for (Thread t : allThreads) {
            t.join();
        }
    }

当我看到所有线程时,线程每次都是混乱的。

【问题讨论】:

  • 集合不需要以任何特定顺序存储线程。如果您希望线程按添加顺序排列,请使用列表。
  • 这里似乎没有任何理由使用HashSet,反正你保证没有重复,所以你只是增加了额外的开销
  • 在 PiRocks 之上说,如果你真的必须使用 Set,请选择一个已订购的,如 TreeSet(任何实现 SortedSet
  • TreeSet 将按元素的自然顺序排序,据我了解问题,顺序应该是插入顺序,而不是自然顺序。

标签: java multithreading threadpool hashset reentrantlock


【解决方案1】:

根据HashSet的文档

这个类实现了 Set 接口,由一个哈希表支持 (实际上是一个 HashMap 实例)。它不保证 集合的迭代顺序;特别是,它不保证 随着时间的推移,订单将保持不变。此类允许 null 元素。

如果您想保持插入顺序的元素,您可以使用例如ArrayListLinkedList

【讨论】:

    【解决方案2】:

    Hashset 不维护顺序,正如 zlaval 所述 - 您可以使用 LinkedList 或 ArrayList。

    但如果你想避免重复并保持插入顺序,你可以使用

    LinkedHashSet

    来自文档:

    Set 接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与 HashSet 的不同之处在于它维护一个双向链表,该列表贯穿其所有条目。这个链表定义了迭代顺序,也就是元素插入集合的顺序(insertion-order)

    【讨论】:

    • 感谢mantioned,它可以节省一些时间。此外,如果没有欺骗或没关系,使用 arraylist 更好,因为它具有更好的性能。
    猜你喜欢
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多