我正在从数据库中读取pdf文件列表,对它们进行解析,并用它们执行一些任务
当我阅读这个pdf列表时,我发现从pdf中提取图像需要花费更多的时间,而且我不需要阻止我的主线程来阅读图像。所以我想在一个单独的线程中执行提取图像
我想从一个又一个pdf中读取图像,而不是一次将所有pdf加载到内存中(由于内存问题)。所以我只想要两条线;一个应该是主线程(从pdf中读取一些文本并执行其他操作),另一个应该是提取图像并返回图像对象集的线程。
这里的一个警告是,来自pdfs的图像在其内容中可能是相同的,所以我想在收集结果之前使用校验和或其他方法删除重复的图像。
我不想在内存中保存图像,直到所有任务完成,我当我得到一个pdf的结果时,想要删除重复的文件
所以真正的问题是,我需要向大小为1的线程池提交多个任务,并且需要在得到结果时删除重复项,这样我就不需要在内存中保存更长时间的映像。
我已经从代码中删除了不必要的东西,比如图像及其内容,并将代码转换为基于字符串的问题。
public static void main(String[] args) throws InterruptedException, ExecutionException {
Map<String, Integer> uniqueImages = new HashMap<>();
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(1);
List<CompletableFuture<String>> futureList = new ArrayList<>();
for(int i = 0; i<20000; i++) {
CompletableFuture<String> obj = CompletableFuture.supplyAsync(()->{
//Assume lot of duplicates
return UUID.randomUUID().toString();
}, newFixedThreadPool).thenApply((x)->{
if(uniqueImages.containsKey(x)) {
int val = uniqueImages.get(x);
uniqueImages.put(x, val+1);
}
else {
uniqueImages.put(x, 1);
}
return x;
});
futureList.add(obj);
}
for(CompletableFuture<String> future: futureList) {
future.get();
}
System.out.println(uniqueImages.size());
}
我担心这段代码是否真的有效或引发ConcurrentModification异常
。
uniqueImages
map真的包含唯一的图像及其计数?只要您只使用大小为1的线程池,就没有问题。
但是,如果有多个线程,那么代码确实不是线程安全的,并且容易出现数据竞争。
我们可以使用以下场景进行演示:
考虑以下代码:
if(uniqueImages.containsKey(x)) {
int val = uniqueImages.get(x);
uniqueImages.put(x, val+1);
}
else {
uniqueImages.put(x, 1);
}
想象线程1和线程2都返回相同的字符串,并到达行if(uniqueImages.containsKey(x))
在一起。if
将在两个线程中返回false,并且uniqueImages.put(x,1);
将在两个线程中被调用。
可能会抛出一个Con电流修改
异常,或者您会得到一个错误的计数(1而不是2)。
如果计划使用多个线程,则必须使用ConcurrentHashMap
。
我必须运行多个外部调用操作,然后以列表的形式获得结果。我决定使用api,而我准备的代码相当恶心: 示例: 我有以下几个问题: > 我可以避免在流中重复块吗?在流中我将CompletableFuture映射到User? 此代码是否可以不那么连续(如何避免等待所有的未来完成?) 这样做可以吗(所有的未来都将在流中解决吗?):
问题内容: 我知道这应该是简单的,我可能正直盯着问题,但我再次陷入困境,需要代码专家的帮助。 我试图从jdbc的一列中取出一行,并将它们放入数组中。 我这样做如下: creatConnection是已经定义的方法,可以执行其明显的工作。我在创建另一个结果集的同时创建了我的结果集,我将该列的字符串存储到一个数组中。然后打印出来以备不时之需。还要确保它在那里。 问题在于其将整个列存储到contactL
我有一个用户类,有16个属性,比如名字,姓氏,出生日期,用户名,密码等...这些都存储在MySQL数据库中,当我想要检索用户时,我使用ResultSet。我想将每一列映射回用户属性,但我这样做的效率似乎非常低。例如,我正在做: 也就是说,我检索所有的列,然后通过将所有的列值插入用户构造函数来创建用户对象。 有人知道更快、更整洁的方法吗?
问题内容: 我正在使用以下内容将检索到的值添加到类中。所有值都将添加到该类的属性中,但是我正在使用compisition(在类中具有class的对象),并且在输出中不显示任何内容。 地址类别如下: 问题答案: 像这样的作品: 将ResultSet行转换为JavaBean。此实现使用反射和BeanInfo类将列名与bean属性名匹配。属性根据以下几个因素与列匹配: 该类具有与列同名的可写属性。名称比
我需要帮助将结果集值从servlet转发到jsp,而不使用JSTL实现 工作流程: 用户在输入框中输入值并单击搜索按钮 单击搜索时会调用servlet。servlet专注于数据库实现并将结果集值转发到请求所在的同一jsp页面。 问题:我的结果集大小是3,但仅表顶部的值就打印在我的jsp页面中。其余2个值缺失。我希望所有的值都打印在我的jsp页面中。 这是我的代码: Productlist.jsp
如果我有一个(或多个)尚未启动,并且在该方法上有几个,方法。 垃圾收集器会移除所有这些吗? 如果在该链的末尾有一个< code > join()/< code > get() 也许我们需要更多关于连接上下文的信息()。 这种连接是线程中的最后一个命令,并且没有副作用。那么在这种情况下,线程仍然是活动的吗?- Java线程垃圾收集与否 无论如何,这是一个好主意,如果我确信(也许在尝试捕获中),那么将