【问题标题】:How to continue a for loop after a certain time without using `try ... catch` method?如何在不使用`try ... catch`方法的情况下在一段时间后继续for循环?
【发布时间】:2016-12-23 05:36:44
【问题描述】:
new Thread(new Runnable() {
    @Override
    public void run() {
        List<Socket> socketList = new ArrayList<>();
        for (String ip: iplist) {
            Socket socket = null;
            try {
                socket = new Socket(ip,23);
            } catch (IOException e) {
                e.printStackTrace();
            }
            socketList.add(socket);
        }
    }
}).start();

我正在尝试为 iplist 中的每个 ip 创建一个新套接字,并将该套接字添加到 sockets 列表中。我为此使用了一个 for 循环。使用 try ... catch 时,当套接字连接失败时,循环执行会暂停很长时间。所以我需要一个更好的替代方法来知道套接字连接失败并通过向套接字列表添加一个空套接字来使循环继续执行。

【问题讨论】:

    标签: java android sockets for-loop java-threads


    【解决方案1】:

    你可以这样做:

    • 使用单独的线程来创建每个套接字。
    • 使用并发集合(而不是List)来存储套接字,例如ConcurrentLinkedDeque
    • 等待所有套接字创建线程完成,然后将并发列表的所有元素添加到普通List(如果需要)。您可以使用例如CompletionService 来实现这一点。

    使用这种方法,失败的套接字仍然需要很长时间,但不会阻止其他套接字的创建。如果每个套接字可以运行一个线程,则创建所有套接字所用的最长时间将是关闭单个失败的时间。

    通过等到所有套接字都创建完成,实现不会与您当前的解决方案在逻辑上背道而驰,它只会更快,而且复杂性将是自包含的。

    另一种选择是不要等到所有套接字都创建完毕,而让所有套接字创建在它们的线程中完成。这将与当前的实现大相径庭,并且处理套接字创建线程的复杂性会影响您的方法之外的代码。

    【讨论】:

    • +1 用于思考线程。我在想java中是否有任何类/方法。还有一个问题,如果一次有很多线程会发生什么?那么JVM需要管理一个巨大的内存,对吧?
    • @Mukit09 确实存在使用线程的内存开销。但是你必须付出一些才能得到一些东西,在这种情况下你会得到更短的执行时间。当然,内存使用量是否巨大取决于线程数。我希望 OP 不打算让 100 个套接字保持活动状态,在这种情况下应该没问题。至于这个类,我不能 100% 确定你的意思,但是并发 API 中有很多有用的类,比如我链接到的几个相关示例。
    猜你喜欢
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多