是一种异步编程模式。可以先开始一个任务的执行,并获得一个任务执行的凭证。等需要这个任务执行的结果时,再凭借方法获取任务执行结果。
使用Future编程的例子如下:
package promise;
import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
public class DataSyncTask implements Runnable {
private final Map<String, String> taskParameters;
public DataSyncTask(Map<String, String> taskParameters) {
this.taskParameters = taskParameters;
}
@Override
public void run() {
String ftpServer = taskParameters.get("server");
String ftpUserName = taskParameters.get("userName");
String password = taskParameters.get("password");
// 初始化ftp客户端实例
Future<FtpClientUtil> ftpClientUtilPromise =
FtpClientUtil.newInstance(ftpServer, ftpUserName, password);
// 查询数据库生成本地文件
generateFilesFromDB();
FtpClientUtil ftpClientUtil = null;
try {
// 获取初始化完毕的FTP客户端实例
ftpClientUtil = ftpClientUtilPromise.get();
} catch (InterruptedException e) {
;
} catch (Exception e) {
throw new RuntimeException(e);
}
uploadFiles(ftpClientUtil);
}
private void generateFilesFromDB() {
}
private void uploadFiles(FtpClientUtil ftpClientUtil) {
Set<File> files = retrieveGeneratedFiles();
for (File file : files) {
try {
ftpClientUtil.upload(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private Set<File> retrieveGeneratedFiles() {
Set<File> files = new HashSet<>();
return files;
}
}
package promise;
import sun.net.ftp.FtpProtocolException;
import sun.net.ftp.FtpReplyCode;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;
/**
* 模式角色:Promise.Promisor
* Promise.Result
*/
public class FtpClientUtil {
private final FtpClient ftp = new FtpClient();
private final Map<String, Boolean> dirCreateMap = new HashMap<>();
private FtpClientUtil() {
}
private volatile static ThreadPoolExecutor threadPoolExecutor;
static {
threadPoolExecutor = new ThreadPoolExecutor(1, Runtime.getRuntime().availableProcessors() * 2,
60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}, new ThreadPoolExecutor.CallerRunsPolicy());
}
/**
* 模式角色:Promise.Promisor.compute
*/
public static Future<FtpClientUtil> newInstance(final String ftpServer, final String userName,
final String password) {
Callable<FtpClientUtil> callable = new Callable<FtpClientUtil>() {
@Override
public FtpClientUtil call() throws Exception {
FtpClientUtil self = new FtpClientUtil();
self.init(ftpServer, userName, password);
return self;
}
};
// task相当于模式角色Promise.Promise
final FutureTask<FtpClientUtil> task = new FutureTask<>(callable);
/**
* 下面创建的线程相当于模式角色:Promise.TaskExecutor
*/
new Thread(task).start();
return task;
}
private void init(final String ftpServer, final String userName,
final String password) throws IOException, FtpProtocolException {
FtpClientConfig config = new FtpClientConfig();
ftp.configure(config);
ftp.connect(ftpServer);
System.out.println(ftp.getLastResponseString());
FtpReplyCode reply = ftp.getLastReplyCode();
if (!reply.isPositiveCompletion()) {
ftp.close();
throw new RuntimeException("FTP server refused connection.");
}
boolean isOK = ftp.login(userName, password);
if (isOK) {
System.out.println(ftp.getLastResponseString());
} else {
throw new RuntimeException("Failed to login." + ftp.getLastResponseString());
}
reply = ftp.cwd("~/subspsync");
if (!reply.isPositiveCompletion()) {
ftp.close();
throw new RuntimeException("Failed to change working directory.reply:" + reply);
} else {
System.out.println(ftp.getLastResponseString());
}
ftp.setFileType(FTP.ASCII_FILE_TYPE);
}
public void upload(File file) throws Exception {
InputStream dataIn = new BufferedInputStream(new FileInputStream(file), 1024 * 8);
boolean isOK;
String dirName = file.getParentFile().getName();
String fileName = dirName + "/" + file.getName();
ByteArrayInputStream checkFileInputStream = new ByteArrayInputStream("".getBytes());
try {
if (!dirCreateMap.containsKey(dirName)) {
ftp.makeDirectory(dirName);
dirCreateMap.put(dirName, null);
}
try {
isOK = ftp.storeFile(fileName, dataIn);
} catch(IOException e) {
throw new RuntimeException("Failed to upload." + file, e);
}
if (isOK) {
ftp.storeFile(fileName + ".c", checkFileInputStream);
} else {
throw new RuntimeException("Failed to upload " + file + ", reply:" +
"," + ftp.getLastResponseString());
}
} finally {
dataIn.close();
}
}
public void disconnect() {
if (ftp.isConnected()) {
try {
ftp.close();
} catch (IOException e) {
// do nothing
}
}
}
}