当前位置: 首页 > 知识库问答 >
问题:

Java尝试使用资源未知资源计数

高英彦
2023-03-14

我需要打开N个多播套接字(其中N来自参数列表的大小)。然后,我将向循环中的N个套接字中的每个套接字发送相同的数据,最后关闭每个套接字。我的问题是,如何使用try with resources块来实现这一点?以下是我将如何使用单个资源来实现这一点:

final int port = ...;
try (final MulticastSocket socket = new MulticastSocket(port)) {
    // Do a bunch of sends of small packet data over a long period of time
    ...
}

我能想到的使用多个端口执行此操作的唯一方法如下:

final List<Integer> ports = ...;
final List<MulticastSocket> sockets = new ArrayList<>(ports.size());
try {
    for (final Integer port : ports) {
        sockets.add(new MulticastSocket(port));
    }

    // Do a bunch of sends of small packet data over a long period of time
    ...
} finally {
    for (final MulticastSocket socket : sockets) {
        try {
            socket.close();
        } catch (final Throwable t) {
            // Eat the exception
        }
    }
}

有没有一种更简洁的方法来实现这一点,或者我提出的解决方案是否尽可能好?

共有3个答案

邢皓
2023-03-14
匿名用户

使用ArrayList存储多播套接字实例有什么意义?

你说过:

然后,我将向循环中的N个套接字中的每个套接字发送相同的数据,最后关闭每个套接字。

因此,您可以在循环中创建它们,并为每次迭代发送相同的处理。
要做到这一点,您应该稍微改变一下您的设计。
MulticastSocket的处理任务可以由一个功能接口执行,该接口也允许指定要使用的端口。

例如:

@FunctionalInterface
public interface SocketProcessor {
    void process(MulticastSocket multicastSocket) ;
}

您可以有一个方法,将此函数接口作为参数来应用处理:

public static void processSocket(SocketProcessor socketProcessor, Integer port) throws IOException {
  try (final MulticastSocket socket = new MulticastSocket(port)) {
    socketProcessor.process(socket);
  }
}

最后,通过客户端代码,您可以创建一个带有lambda的socketProcessor实例:

SocketProcessor socketProcessor = (MulticastSocket socket) -> {
    socket.send(...);
    socket.send(...);
};

然后,您可以在端口上循环,以便使用合适的端口和刚刚创建的SocketProcator实例调用过程Socket:

for (final Integer port : ports) {
    try {
      processSocket(socketProcessor, port);
    } catch (IOException e) {
      // do processing
    }
}

这个解决方案不一定要更短(而不是更长),但它确实更清晰
两个主要问题是分开的:

>

定义具体任务的SocketProcessor。

卫景明
2023-03-14

你所做的几乎和它得到的一样好。

您可以创建一个AutoCloseable通用多闭包,其中包含一个List

try( MultiCloser<MulticastSocket> multiCloser = 
         new MultiCloser<>( ports.size(), i -> new MulticastSocket( ports.get( i ) ) )
{
    for( MulticastSocket socket : multiCloser.getItems() )
    {
        do something with the socket
    }
}

...但这可能是一种过度杀戮。

司徒经纶
2023-03-14

以递归的方式进行,以保证使用资源进行尝试:

void foo(List<Integer> ports, List<Socket> sockets) {
  if (sockets.size() == ports.size()) {
    // Do something with your sockets.
  } else {
    try (Socket s = new MulticastSocket(ports.get(sockets.size())) {
      sockets.add(s);
      foo(ports, sockets);
      // You could call sockets.remove(sockets.size()-1) here.
      // Not convinced whether it's worth it.
    }
  }
}
 类似资料:
  • 问题内容: 我一直在看代码,并且看到了尝试资源的机会。我以前使用过标准的try-catch语句,看起来它们在做同样的事情。所以我的问题是“ 尝试使用资源”与“尝试捕获 ”之间的区别是什么,哪个更好。 这是尝试使用资源: 问题答案: 尝试使用资源的重点是确保可靠地关闭资源。 当你不使用try-with-resources时,存在一个潜在的陷阱,称为异常屏蔽。当try块中的代码引发异常,而finall

  • 我知道,如果资源已实现自动关闭,您通过尝试传递的资源将自动关闭。到现在为止,一直都还不错。但是,当我有几个我想要自动关闭的资源时,我该怎么办呢。带插座的示例; 所以我知道套接字将被正确关闭,因为它在try中作为参数传递,但是输入和输出应该如何正确关闭呢?

  • 不管错误情况如何,使用资源尝试是否总是关闭资源?我的意思是考虑以下代码: 会一直关闭吗?我读过Oracle文档,其中说: 无论try语句是正常完成还是突然完成,它都将关闭 因此无论程序正常运行还是抛出异常,它都将起作用。但是,类似或崩溃的情况怎么办?我知道这些条件对块不起作用。那么,使用资源尝试失败的条件是否存在? 这只是我请求的好奇心,谁能说明这一点吗?

  • 问题内容: 我是的新手,我想知道对于资源来说,我是否必须为每个添加一个,否则它将与上面的代码一起使用 问题答案: 通过在 块中声明所有资源,可以尝试将资源与多个资源一起使用,并且此功能是 Java 7中 引入的,而不是 Java 8中 引入的。如果有多个资源,则可以如下所示 在此示例中,该语句包含两个用分号分隔的声明: ZipFile 和 BufferedWriter 。当它紧随其后的代码块终止时

  • 我认为流API在这里是为了使代码更易于阅读。我觉得有点烦。流接口扩展了java。lang.AutoCloseable接口。 因此,如果你想正确地关闭流,你必须使用try-with资源。 清单1.不是很好,流没有关闭。 清单2.使用2嵌套try 清单3。当map返回流时,必须关闭stream()和map()函数。 我举的例子毫无意义。为了示例,我将jpg图像的路径替换为整数。但不要让这些细节分散你的

  • 我是新手,我想知道,对于资源,我是否必须为每个