在自定义线程池上运行Play作业

时间:2012-12-04 21:15:22

标签: playframework playframework-1.x

我想在自定义线程池/执行程序服务上运行一些作业。

原因是我有很多工作可能会压倒正常的工作池,所以我想将它们分成一个专用池。

我尝试创建一个新的ExecutorService并在其上运行作业:

public static <T> F.Promise<T> runJobWithExecutor(ExecutorService executor, final Job<T> job) {
    final F.Promise<T> promise = new F.Promise<T>();
    executor.submit(new Callable<T>() {
        public T call() throws Exception {
            T result =  job.call();
            promise.invoke(result);
            return result;
        }
    });
    return promise;
}

但是我遇到了各种JPA错误:

  

以下失败导致SQLException:   java.lang.InterruptedException [原因:java.lang.InterruptedException   在java.lang.Object.wait(Native Method)at   com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)   在   com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)   在   com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)   在   com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)   在   com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)   在   org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:71)   在   org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)   在   org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)   在org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160)at   org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81)   在   org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473)   在org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:60)at   play.db.jpa.JPAPlugin.startTx(JPAPlugin.java:350)at at   play.db.jpa.JPAPlugin.beforeInvocation(JPAPlugin.java:318)at at   play.plugins.PluginCollection.beforeInvocation(PluginCollection.java:428)   在play.Invoker $ Invocation.before(Invoker.java:217)at   play.jobs.Job.call(Job.java:139)at   org.commercesciences.play.Jobs3 $ 1.call(Jobs3.java:16)at   java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:334)at at   java.util.concurrent.FutureTask.run(FutureTask.java:166)at   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)   在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:603)   在java.lang.Thread.run(Thread.java:722)

为了在不同的线程上运行作业,还有什么需要做的吗?

我正在使用play 1.2.4-mbknor-3。

1 个答案:

答案 0 :(得分:1)

与您的问题背景相关的一些事情(即使不是对它的直接回应)。

1)。 尝试更改最大队列大小。

int maxThreads = 50;
int queueSize = 1000; // should be big enough!
ExecutorService newExecutor = new ThreadPoolExecutor(maxThreads, maxThreads, Long.MAX_VALUE, TimeUnit.NANOSECONDS, new ArrayBlockingQueue<Runnable>(queueSize, true));

2)。 另外,在性能方面,如果你不需要Hibernate,可以考虑Callable而不是Job - play!的Job本质上非常重,它根据需要初始化Hibernate和其他插件,每个Job。