如何使用API java.util.concurrent.Future而不是在java中显式创建线程?
我有两个线程在java程序中并行运行,如下所示:如何使用API java.util.concurrent.Future而不是在java中显式创建线程?,java,multithreading,Java,Multithreading,我有两个线程在java程序中并行运行,如下所示: // Threading new Thread(new Runnable() { @Override public void run() { try { gpTableCount = getGpTableCount(); } catch (SQLException e) { e.printStackTrace(); } catch(
// Threading
new Thread(new Runnable() {
@Override
public void run() {
try {
gpTableCount = getGpTableCount();
} catch (SQLException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
hiveTableCount = getHiveTableCount();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
while(!(gpTableCount != null && gpTableCount.size() > 0 && hiveTableCount != null && hiveTableCount.size() > 0)) {
Thread.sleep(5000);
}
// Threading
它们都具有相同的功能。下面是getHiveTableCount()中的代码。另一种方法与下面的方法略有不同(一两行),但功能保持不变
public Map<String, String> getHiveTableCount() throws IOException, SQLException {
hiveDataMap = new HashMap<String, String>();
hiveTableErrs = new HashMap<String, String>();
Iterator<String> hiveIterator = filteredList.iterator();
Connection hiveConnection = DbManager.getHiveConnection();
PreparedStatement hive_pstmnt = null;
String hiveExcpnMsg;
String ssn;
String hiveMaxUpdTms;
Long hiveCount;
String gpHiveRec;
String[] hiveArray;
String[] hiveDetails;
String hiveQuery;
while(hiveIterator.hasNext()) {
gpHiveRec = hiveIterator.next();
hiveArray = gpHiveRec.split(",");
hiveDetails = hiveArray[1].split("\\.");
hiveQuery = "select '" + hiveDetails[1] + "' as TableName, count(*) as Count, source_system_name, max(xx_last_update_tms) from " + hiveArray[1] + " where source_system_name='" + hiveArray[2] + "' group by source_system_name";
try {
hive_pstmnt = hiveConnection.prepareStatement(hiveQuery);
ResultSet hiveCountRs = hive_pstmnt.executeQuery();
while(hiveCountRs.next()) {
hiveCount = hiveCountRs.getLong(2);
ssn = hiveCountRs.getString(3);
hiveMaxUpdTms = hiveCountRs.getTimestamp(4).toString();
hiveDataMap.put(hiveDetails[1] + "," + ssn, hiveCount + "," + hiveMaxUpdTms);
}
} catch(org.postgresql.util.PSQLException e) {
hiveExcpnMsg = e.getMessage();
hiveTableErrs.put(hiveDetails[1] + ": for the SSN: " + hiveArray[2], hiveExcpnMsg + "\n");
} catch(SQLException e) {
hiveExcpnMsg = e.getMessage();
hiveTableErrs.put(hiveDetails[1] + ": for the SSN: " + hiveArray[2], hiveExcpnMsg + "\n");
} catch(Exception e) {
hiveExcpnMsg = e.getMessage();
hiveTableErrs.put(hiveDetails[1] + ": for the SSN: " + hiveArray[2], hiveExcpnMsg + "\n");
}
}
return hiveDataMap;
}
公共映射getHiveTableCount()引发IOException、SQLException{
hiveDataMap=新HashMap();
hiveTableErrs=新HashMap();
迭代器hiveIterator=filteredList.Iterator();
连接hiveConnection=DbManager.getHiveConnection();
PreparedStatement配置单元\pstmnt=null;
字符串HIVEEXCPNMG;
字符串ssn;
字符串hiveMaxUpdTms;
长hiveCount;
字符串gpHiveRec;
字符串[]hiveArray;
字符串[]hiveDetails;
字符串hiveQuery;
while(hiveIterator.hasNext()){
gpHiveRec=hiveIterator.next();
hiveArray=gpHiveRec.split(“,”);
hiveDetails=hiveArray[1]。拆分(“\\”);
hiveQuery=“选择”+hiveDetails[1]+“”作为表名,count(*)作为计数,source\u system\u name,max(xx\u last\u update\u tms)来自“+hiveArray[1]+”其中source\u system\u name=”“+hiveArray[2]+“‘按源系统名称分组’;
试一试{
HivepstMNT=hiveConnection.prepareStatement(hiveQuery);
ResultSet hiveCountRs=Hivepstmnt.executeQuery();
while(hiveCountRs.next()){
hiveCount=hiveCountRs.getLong(2);
ssn=hiveCountRs.getString(3);
hiveMaxUpdTms=hiveCountRs.getTimestamp(4.toString();
hiveDataMap.put(hiveDetails[1]+“,+ssn,hiveCount+”,“+hiveMaxUpdTms);
}
}catch(org.postgresql.util.psqle){
HIVEEXCPNMG=e.getMessage();
hiveTableErrs.put(hiveDetails[1]+”:对于SSN:“+hiveArray[2],hiveExcpnMsg+”\n”);
}捕获(SQLE异常){
HIVEEXCPNMG=e.getMessage();
hiveTableErrs.put(hiveDetails[1]+”:对于SSN:“+hiveArray[2],hiveExcpnMsg+”\n”);
}捕获(例外e){
HIVEEXCPNMG=e.getMessage();
hiveTableErrs.put(hiveDetails[1]+”:对于SSN:“+hiveArray[2],hiveExcpnMsg+”\n”);
}
}
返回hiveDataMap;
}
这两个线程同时运行。我最近在网上看到:
Future类表示异步计算的未来结果
–最终将在未来的
处理完成
我从理论上理解了这个概念,但我不知道如何将java.util.concurrent.Future api应用于上述相同的代码,而不是显式地创建线程。
有人能告诉我如何使用java.util.concurrent.Future api在方法上实现多线程:
getGpTableCount()&getHiveTableCount
而不是创建线程创建新线程,比如new Thread(new Runnable())?您正在使用Runnable
接口提交任务,该接口不允许线程在计算结束时返回值(并导致您使用共享变量-gpTableCount
和hiveTableCount
)
可调用
接口是稍后添加的一个接口,它允许任务返回一个值(在您的示例中为映射
)
作为直接处理线程的替代方法,并发API引入了ExecutorService
,作为更高级别的对象,它管理线程池并能够异步执行任务
将类型为Callable
的任务提交给ExecutorService
时,您希望该任务产生一个值,但由于提交点和计算结束点没有耦合,因此ExecutorService
将返回Future
,允许您获取该值,并在该值不可用时阻止。因此,Future
可用于在不同线程之间进行同步
作为ExecutorService
的替代方案,您还可以查看FutureTask
,它是RunnableFuture
的实现:
此类提供了Future
的基本实现,其中包含启动和取消计算、查询以查看计算是否完成以及检索计算结果的方法
FutureTask可用于包装可调用或可运行的对象
首先,创建最适合您需要的executor服务,例如:
ExecutorService ex = Executors.newFixedThreadPool(2);
(更多关于遗嘱执行人的信息:)
使用Callable代替Runnable对象,Callable类似于Runnable,但返回一个值(更多关于Callable:):
如果您使用的是Java 8+,您可以使用
CompletableFuture.supplyAsync
来实现这一点,简而言之,类似:
import static java.util.concurrent.CompletableFuture.supplyAsync;
.....
Future<Map<String, String>> f= supplyAsync(()->{
try{
return getHiveTableCount();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
而且它有
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
Executor executor)
public static completable未来供应同步(供应商)
公共静态可完成未来供应同步(供应商,
执行人(执行人)
查看ThreadPoolExecutor
List<Future<Map<String, String>>> results = ex.invokeAll(tasks);
ex.shutdown();
import static java.util.concurrent.CompletableFuture.supplyAsync;
.....
Future<Map<String, String>> f= supplyAsync(()->{
try{
return getHiveTableCount();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
public class CompletableFuture<T>
extends Object
implements Future<T>, CompletionStage<T>
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
Executor executor)