Java 告诉ThreadPoolExecutor何时应该进行或不进行
我必须通过某个端口向几台计算机发送一组文件。事实上,每次调用发送文件的方法时,都会计算目标数据(地址和端口)。因此,使用一个循环,为每个方法调用创建一个线程,并用BindException的try-catch语句围绕方法调用,以处理程序试图使用已在使用的端口的情况(不同的目标地址可能通过同一端口接收消息)告诉线程等待几秒钟,然后重新启动以重试,并继续尝试,直到未引发异常为止(传送已成功执行)。 我不知道为什么(虽然我第一次看到它时可以猜到),Netbeans警告我在循环中休眠线程对象不是最佳选择。然后我在谷歌上搜索了一些进一步的信息,发现了(我从来没有听说过)。为了改进我的程序,我一直在阅读这个链接和API,但是我还不确定我应该如何在我的程序中应用它。谁能帮我一把吗 编辑:重要代码:Java 告诉ThreadPoolExecutor何时应该进行或不进行,java,multithreading,port,threadpool,threadpoolexecutor,Java,Multithreading,Port,Threadpool,Threadpoolexecutor,我必须通过某个端口向几台计算机发送一组文件。事实上,每次调用发送文件的方法时,都会计算目标数据(地址和端口)。因此,使用一个循环,为每个方法调用创建一个线程,并用BindException的try-catch语句围绕方法调用,以处理程序试图使用已在使用的端口的情况(不同的目标地址可能通过同一端口接收消息)告诉线程等待几秒钟,然后重新启动以重试,并继续尝试,直到未引发异常为止(传送已成功执行)。 我不知道为什么(虽然我第一次看到它时可以猜到),Netbeans警告我在循环中休眠线程对象不是最佳选择
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;
}
}
}
for(Iterator it=ConnectionsPanel.list.getSelectedValuesList().Iterator();it.hasNext();){
最后一个字符串x=it.next();
新线程(){
@凌驾
公开募捐{
ConnectionsPanel.singleAddVideos(x);
}
}.start();
}
私有静态void singleAddVideos(字符串名称){
字符串newVideosInfo=“”;
for(Iterator 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);
}
}捕获(bindex异常){
MassiveDesktopClient.println(“试图使用已在使用的端口。正在等待并重试…”,新异常().getStackTrace()[0]。getLineNumber());
试一试{
休眠(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS*1000);
}捕获(中断异常ex1){
showMessageDialog(null,ex1.toString(),“Error”,JOptionPane.Error\u消息);
}
ConnectionsPanel.singleAddVideos(connName);
返回;
}
for(Iterator it=ConnectionsPanel.videosToSend.Iterator();it.hasNext();){
试一试{
MassiveDesktopClient.sendFile(it.next().getAttribute(“名称”),connName);
}捕获(bindex异常){
MassiveDesktopClient.println(“试图使用已在使用的端口。正在等待并重试…”,新异常().getStackTrace()[0]。getLineNumber());
试一试{
休眠(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS*1000);
}捕获(中断异常ex1){
showMessageDialog(null,ex1.toString(),“Error”,JOptionPane.Error\u消息);
}
ConnectionsPanel.singleAddVideos(connName);
返回;
}
}
}
您的问题不太清楚-我知道您希望重新运行任务,直到任务成功(无例外)。为此,您可以:
- 尝试在不捕获异常的情况下运行代码
- 从未来捕获异常
- 如果任务失败,请稍后重新安排任务
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);
}
}
}
publicstaticvoidmain(字符串[]args)引发异常{
ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(corePoolSize);
最终字符串x=“视频”;
Callable yourTask=new Callable(){
@凌驾
public Void call()引发异常{
ConnectionsPanel.singleAddVideos(x);
返回null;
}
};
Future f=调度程序。提交(您的任务);
boolean added=false;//将重试,直到成功
//您可以改为使用int来重试
//仅n次,避免无限循环的风险
而(!已添加){
试一试{
f、 get();
added=true;//如果未捕获异常,则将集合添加为true
}捕获(执行例外){
if(例如getCause()instanceof BindException){
scheduler.schedule(您的任务,3,TimeUnit.SECONDS);//在3秒内重新安排
}否则{
//引发了另一个异常=>处理它
}
}
}
}
公共静态类连接面板{
私有静态void singleAddVideos(字符串connName)引发BindException{
字符串newVideosInfo=“”;
for(Iterator 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 it=ConnectionsPanel.videosToSend.Iterator();it.hasNext();){
MassiveDesktopClient.sendFile(it.next().getAttribute(“名称”),connName);
}
}
}
不要谈论它,你应该发布代码本身。如果你将用户名更改为真实用户名,我会+1告诉你,那么你将有一个21的代表,足以访问stackoverflow聊天(在顶部的评论链接旁边)。因为你问的不是问题。我认为改名的可能性需要最低的声誉,对不起,伙计@MarkoTopolnik,代码已添加。感谢您的关注(我认为最好是解释而不是代码)。您的问题是s