有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java告诉ThreadPoolExecutor何时应该进行或不进行

我必须通过某个端口向几台计算机发送一组文件。事实上,每次调用发送文件的方法时,都会计算目标数据(地址和端口)。因此,使用为每个方法调用创建线程的循环,并使用BindException的try-catch语句包围方法调用,以处理程序试图使用已在使用的端口(不同的目标地址可能通过同一端口接收消息)的情况,告知线程等待几秒钟,然后重新启动以重试,并继续尝试,直到未引发异常(成功执行传送)。 我不知道为什么(虽然我第一次看到它时可以猜到),Netbeans警告我在循环中休眠线程对象不是最佳选择。然后我在谷歌上搜索了一些进一步的信息,找到了this link to another stackoverflow post, which looked so interesting(我从来没有听说过the ThreadPoolExecutor class)。为了改进我的程序,我一直在阅读这个链接和API,但是我还不确定我应该如何在我的程序中应用它。谁能帮我一把吗

编辑:重要代码:

        for (Iterator<String> it = ConnectionsPanel.list.getSelectedValuesList().iterator(); it.hasNext();) {
        final String x = it.next();
        new Thread() {

            @Override
            public void run() {
                ConnectionsPanel.singleAddVideos(x);
            }
        }.start();
    }

    private static void singleAddVideos(String connName) {
    String newVideosInfo = "";

    for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
        newVideosInfo = newVideosInfo.concat(it.next().toString());
    }

    try {
        MassiveDesktopClient.sendMessage("hi", connName);
        if (MassiveDesktopClient.receiveMessage(connName).matches("hello")) {
            MassiveDesktopClient.sendMessage(newVideosInfo, connName);
        }
    } catch (BindException ex) {
        MassiveDesktopClient.println("Attempted to use a port which is already being used. Waiting and retrying...", new Exception().getStackTrace()[0].getLineNumber());
        try {
            Thread.sleep(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS * 1000);
        } catch (InterruptedException ex1) {
            JOptionPane.showMessageDialog(null, ex1.toString(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        ConnectionsPanel.singleAddVideos(connName);
        return;
    }

    for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
        try {
            MassiveDesktopClient.sendFile(it.next().getAttribute("name"), connName);
        } catch (BindException ex) {
            MassiveDesktopClient.println("Attempted to use a port which is already being used. Waiting and retrying...", new Exception().getStackTrace()[0].getLineNumber());
            try {
                Thread.sleep(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS * 1000);
            } catch (InterruptedException ex1) {
                JOptionPane.showMessageDialog(null, ex1.toString(), "Error", JOptionPane.ERROR_MESSAGE);
            }
            ConnectionsPanel.singleAddVideos(connName);
            return;
        }
    }
}

共 (1) 个答案

  1. # 1 楼答案

    你的问题不是很清楚——我知道你想重新运行你的任务,直到它成功(没有例外)。要做到这一点,你可以:

    • 尝试在不捕获异常的情况下运行代码
    • 捕捉未来的例外
    • 如果任务失败,请稍后重新安排任务

    一个简化的代码如下-添加错误消息并根据需要进行优化:

    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(corePoolSize);
        final String x = "video";
        Callable<Void> yourTask = new Callable<Void>() {
            @Override
            public Void call() throws BindException {
                ConnectionsPanel.singleAddVideos(x);
                return null;
            }
        };
        Future f = scheduler.submit(yourTask);
        boolean added = false; //it will retry until success
                               //you might use an int instead to retry
                               //n times only and avoid the risk of infinite loop
        while (!added) {
            try {
                f.get();
                added = true; //added set to true if no exception caught
            } catch (ExecutionException e) {
                if (e.getCause() instanceof BindException) {
                    scheduler.schedule(yourTask, 3, TimeUnit.SECONDS); //reschedule in 3 seconds
                } else {
                    //another exception was thrown => handle it
                }
            }
        }
    }
    
    public static class ConnectionsPanel {
    
        private static void singleAddVideos(String connName) throws BindException {
            String newVideosInfo = "";
    
            for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
                newVideosInfo = newVideosInfo.concat(it.next().toString());
            }
    
            MassiveDesktopClient.sendMessage("hi", connName);
            if (MassiveDesktopClient.receiveMessage(connName).matches("hello")) {
                MassiveDesktopClient.sendMessage(newVideosInfo, connName);
            }
    
            for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
                MassiveDesktopClient.sendFile(it.next().getAttribute("name"), connName);
            }
        }
    }