方案。更多主题。每个线程都希望打开自己的FTP连接到同一个FTP服务器。那是因为我有一个BlockingQueue
个要发送的文件,我希望每个线程都有一个文件供队列处理。
现在:我的FTPClass就像这样(Just Constructor Offering)。
public class FtpHandler {
private boolean login;
private boolean connect;
private final String server;
private final String username;
private final String password;
private int replyCode;
private String replyString;
private final int ftpMbSize;
private FTPClient ftpClient;
public FtpHandler(String server, String username, String password, int ftpMbSize) throws SocketException, IOException {
this.server = server;
this.username = username;
this.password = password;
this.login = false;
this.ftpMbSize = ftpMbSize;
ftpClient = new FTPClient();
ftpClient.connect(this.server);
replyCode = ftpClient.getReplyCode();
replyString = ftpClient.getReplyString();
if (FTPReply.isPositiveCompletion(replyCode)) {
connect = true;
if (ftpClient.login(username, password)) {
login = true;
} else {
login = false;
connect = false;
ftpClient.disconnect();
}
} else {
ftpClient.disconnect();
connect = false;
}
}
}
完美,现在run方法中的每个线程(称为Sender
)都是这样的:
@Override
public void run() {
FtpHandler ftpHandler = null;
try {
logger.info(jobname, "OPEN CONNECTION FTP TO " + appConfig.getSender_ftp_name());
/*
* IF FTP HANDLER THROW AN ERROR
* -> CATCH GOES IN ACTION
*/
ftpHandler = new FtpHandler(appConfig.getSender_ftp_ip(),
appConfig.getSender_ftp_username(),
appConfig.getSender_ftp_password(),
appConfig.getSender_ftp_bufferSize_Mb());
} catch (Throwable thw) {
//Do Something to handle exception
} finally {
//IF FTP IS CONNECTED -> CLOSE IT
if (ftpHandler != null && (ftpHandler.isLogin() || ftpHandler.isConnect())) {
ftpHandler.disconnect();
}
}
}
现在,正如您所看到的,每个线程都创建了一个自己的FtpHandler类实例,因此它可以自己管理FTP连接。
现在问题:它发生了,几乎每次都会发生(它也不会发生),Just a Single线程可以正确地打开连接来做某事(好吧,这个线程将管理所有文件),同时另一个线程将等待第一个关闭它以便能够打开。
我想知道我做错了什么。
TL; DR:是否可以打开与同一FTP服务器的不同FTP连接?
添加创建BlockingQueue和Threads的Controller类实现:
BlockingQueue<FileRec> queue = new ArrayBlockingQueue<>(filesList.size());
for (FileRec fileRec : filesList) {
queue.add(fileReccomender);
}
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 1; i <= appConfig.getController_sender_nThreads() && i <= filesList.size(); i++) {
Sender sender = new Sender(queue, i);
executor.execute(sender);
}
executor.shutdown();
while (!executor.isTerminated()) {
}