两个串行任务比并行慢

时间:2010-02-09 15:15:39

标签: java

您好我有一个webapp - 在一种方法中,我需要从请求中加密部分数据并将它们存储在磁盘上并返回响应。

响应与加密无关。

然而,加密时间要求很高。如何在这个问题上正确地创建线程?

我试过像

这样的东西

线程线程......

thread.start();

JobDetail job = encryptionScheduler.getJobDetail(jobDetail.getName(),jobDetail.getGroup());

encryptionScheduler.scheduleJob(的JobDetail,TriggerUtils.makeImmediateTrigger( “encryptionTrigger”,1,1)

我尝试了servlet,在加密之前我关闭了outpuStream。

或:Executors.newFixedThreadPool(1);

但无论我尝试了什么,客户都必须等待更长时间。

顺便问一下:为什么会这样?可以更快吗?

我没有尝试在上下文初始化之后启动线程并等待某种方法需要加密。

如何加快这个?

谢谢

--------------编辑: //我使用了轴1.4,我有Handler,它在调用方法中加密一个值:

try {
    LogFile logFile = new LogFile(strategy,nodeValue,path, new Date());
    LogQueue.queue.add(logFile);
    }
    catch (Exception e) {
        log.error(e.getMessage(),e);
    }

EExecutor.executorService.execute(new Runnable() {
            public void run() {
                try {
                LogFile poll = LogQueue.queue.poll();
                String strategy = poll.getStrategy();
                    String value = poll.getNodeValue();
                    value = encrypt(strategy,value);
                    PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(poll.getPath(), true )),"UTF-8"));
                    writer.print(value);
                    writer.close();
                }catch (IOException e  ) {
                    log.error(e.getMessage(),e);
                } 
            }

        });
        } catch (Throwable e ) {
            log.error(e.getMessage(),e);
        }

//除了我有执行者服务

public class EExecutor { public static ExecutorService executorService = Executors.newCachedThreadPool();}

//什么是真正有趣的..当我将加密从这个处理程序移动到另一个被调用的处理程序时 最后当我发送回复!它更快。但是当我收到请求时,我将其留在第一个处理程序中。如果不使用线程/ servlet等,它甚至会更慢。

2 个答案:

答案 0 :(得分:5)

如果您的任务的某些部分可以并行完成,则线程只会帮助您。听起来你在等待加密完成后才返回结果。如果您需要这样做(例如,因为加密数据 结果),那么在单独的线程上进行加密对您没有帮助 - 它所做的只是介绍创建和切换到不同线程的开销。

编辑:如果您为每次加密启动主题,那么这可能是您问题的一部分。创建新线程相对昂贵。更好的方法是使用具有无界队列的ExecutorService。如果你不关心加密步骤发生的顺序(即,如果由于在时间t的请求而开始的加密完成的时间晚于在时间t'开始的加密,并且t< t' ),那么你可以让ExecutorService拥有多个线程。这将为您提供更高的并发性,并为您节省始终重新创建线程的开销,因为ExecutorService池并重用线程。

答案 1 :(得分:0)

执行此类操作的正确方法是使用message queue,例如标准J2EE JMS

在消息队列中,您有一个软件组件,其作用是接收消息(例如加密某些资源的请求,如您的情况),并以事务方式使请求“持久”。然后,一些独立的进程轮询消息队列以获取新消息,对它们采取操作,并在事务上将消息标记为已接收。