我在同一个线程中修改循环中的对象时遇到问题,如果修改在不同的线程中完成,修改似乎工作正常。
这是我为此编写的代码。
父方法调用是:
public void task(){
List<URLTask> tasks = dService.getTasksForStatusReport(System.currentTimeMillis());
System.out.println("scheduler called to send mail");
this.sendMail(tasks,false);
}
获取任务列表的服务:
public List<URLTask> getTasksForStatusReport(long timestamp) {
PersistenceManager pm = pmf.getPersistenceManager();
Query q = pm.newQuery("SELECT FROM " + URLTask.class.getName() + " WHERE nextMailTimestamp <= "+timestamp+" && isDeleted != true");
List<URLTask> c = (List<URLTask>)q.execute();
pm.detachCopyAll(c);//I have tried commenting and uncommenting this line but no effect
return c;
}
sendMail(tasks,boolean)的代码如下:
public void sendMail(List<URLTask> tasks , boolean consolidatedEmail){
for(URLTask task: tasks){
task.setNextMailTimestamp(System.currentTimeMillis() + task.getMailIntervalInMilliseconds());
dService.saveUrlTask(task);
}
}
}
saveUrlTask(task)方法是:
public URLTask saveUrlTask(URLTask task) {
PersistenceManager pm = pmf.getPersistenceManager();
Transaction tx = pm.currentTransaction();
URLTask taskCopy;
tx.begin();
Query q = pm.newQuery("SELECT FROM " + URLTask.class.getName() +
" WHERE isDeleted != 0 && id == \"" + task.getId() + "\"");
long bfr = System.currentTimeMillis();
List<URLTask> taskList = (List<URLTask>)q.execute();
long aft = System.currentTimeMillis();
System.out.println("getting url task time = "+ (aft-bfr));
URLTask oldTask = taskList.get(0);
oldTask.setRepeatIntervalInSeconds(task.getRepeatIntervalInSeconds());
oldTask.setUrl(task.getUrl());
oldTask.setDeleted(task.isDeleted());
oldTask.setNextMailTimestamp(task.getNextMailTimestamp());
oldTask.setMailIntervalInMilliseconds(task.getMailIntervalInMilliseconds());
oldTask.setUserDefinedErrorMessages(task.getUserDefinedErrorMessages());
oldTask.setUpdateTimeStamp(System.currentTimeMillis());
oldTask.setMailIntervalInMilliseconds(task.getMailIntervalInMilliseconds());
oldTask.setNextMailTimestamp(task.getNextMailTimestamp());
oldTask.setUserDefinedErrorMessages(task.getUserDefinedErrorMessages());
bfr = System.currentTimeMillis();
pm.makePersistent(oldTask);
aft = System.currentTimeMillis();
System.out.println("updating url task time = "+ (aft-bfr));
taskCopy = (URLTask)(pm.detachCopy(oldTask));
tx.commit();
pm.close();
return taskCopy;
}
当列表的大小为1并且大小为2时,代码可以正常工作,第一次运行时它可以正常工作,但第二次运行时会抛出异常。
作为参考,例外是:
Exception in thread "HBase Connection Evictor" java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1768)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:767)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:658)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBatch(HConnectionManager.java:1143)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBatchOfPuts(HConnectionManager.java:1241)
at org.apache.hadoop.hbase.client.HTable.flushCommits(HTable.java:826)
at org.apache.hadoop.hbase.client.HTable.close(HTable.java:838)
at org.datanucleus.store.hbase.HBaseManagedConnection.closeTables(HBaseManagedConnection.java:169)
at org.datanucleus.store.hbase.HBaseManagedConnection.dispose(HBaseManagedConnection.java:154)
at org.datanucleus.store.hbase.HBaseConnectionPool.disposeTimedOutConnections(HBaseConnectionPool.java:94)
at org.datanucleus.store.hbase.HBaseConnectionPool.access$000(HBaseConnectionPool.java:27)
at org.datanucleus.store.hbase.HBaseConnectionPool$1.run(HBaseConnectionPool.java:105)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
任何形式的帮助都会非常明显。
提前致谢!!
devsri