Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java web app中的并发文件处理跟踪_Java_Multithreading_Web Applications_Concurrency_Executorservice - Fatal编程技术网

Java web app中的并发文件处理跟踪

Java web app中的并发文件处理跟踪,java,multithreading,web-applications,concurrency,executorservice,Java,Multithreading,Web Applications,Concurrency,Executorservice,我有一个Java1.5Web应用程序,可以将任意PDF文件转换为图像。一次处理一个PDF文件的所有页面需要很长时间,所以我想按需处理页面 当特定页面的HTTP请求到达时,我必须在一个新线程中启动/排队映像生成操作。我如何确保我不会将重复操作(例如,两个用户从同一PDF请求同一页面)排入队列,而不用求助于单线程执行器?我如何使用诸如同步列表之类的东西来跟踪工作线程正在处理哪些图像(或者,什么类型的同步机制可以帮助我跟踪这些图像)?您可以使用或来跟踪哪些PDF已被处理(并且可能已缓存)或当前正在处理

我有一个Java1.5Web应用程序,可以将任意PDF文件转换为图像。一次处理一个PDF文件的所有页面需要很长时间,所以我想按需处理页面


当特定页面的HTTP请求到达时,我必须在一个新线程中启动/排队映像生成操作。我如何确保我不会将重复操作(例如,两个用户从同一PDF请求同一页面)排入队列,而不用求助于单线程执行器?我如何使用诸如同步列表之类的东西来跟踪工作线程正在处理哪些图像(或者,什么类型的同步机制可以帮助我跟踪这些图像)?

您可以使用或来跟踪哪些PDF已被处理(并且可能已缓存)或当前正在处理。为您的PDF图像请求使用a;当工作线程从队列中提取请求时,它会将其添加到集合/映射中,如果添加成功,则线程会处理该请求,如果添加失败,则请求已在容器中。

您可以使用带有PDF标识符(例如文件路径等)的
ConcurrentHashMap
作为键和任务,将转换操作本身表示为值

ConcurrentHashMap
putIfAbsent
方法可以处理比较和设置操作的问题,
Future
isDone
方法可以指示转换是否完成

putIfAbsent
返回
null
时,意味着给定PDF的转换任务还不存在,因此您需要调用
ExecutorService.submit(可调用任务)
来启动新创建的转换任务;否则,您将忽略此步骤并等待已存在的任务完成

模型:

Future<String> conversionTask = ... // blah
Future<String> existingTask = conversions.putIfAbsent(pdfId, conversionTask);
if (existingTask != null) {
    conversionTask = existingTask;
}
// Either way, conversion is scheduled by now.
未来转换任务=…//废话
Future existingTask=conversions.putIfAbsent(pdfId,conversionTask);
if(existingTask!=null){
转换任务=现有任务;
}
//不管是哪种方式,转换现在已经安排好了。
ExecutorService
负责将转换请求排队

转换完成后,可以通过
Future.get()
方法检索结果


请注意,规范不允许在JavaEE应用程序中生成线程。一种常见的方法是将异步处理分离为JMS服务,这对您有所帮助。

这是一个很好的问题;对此有一些不好的解释,但正确的解释有点棘手。例如,您可能无法简单地使用同步,因为它可能会带来严重的性能损失。让我考虑一下,看看我是否能帮到你……”例如,你可能不能简单地使用同步,因为它可能会带来严重的性能损失。”-如果有很多人同时请求PDF,你只会得到显著的性能损失。很可能情况并非如此。最好保守地进行同步。。。然后再担心潜在的瓶颈。@StephenC就过早优化而言,我不得不同意你的看法。Java的内置并发类比坚持使用
synchronized
关键字做得更好。当
ConcurrentXYZ
已经是线程安全的(而且更快)时,为什么要显式同步?另外,在调用
包含
添加
之间,可以是来自另一个线程的并发写入
add
返回一个
boolean
值,该值指示内容是否已更改(添加发生)或未更改(项目已存在),因此最好不要在此处使用
contains
——比较和设置必须是原子的。