Я сталкиваюсь с проблемой при изменении объекта в цикле в том же потоке, и модификация, кажется, работает нормально, если изменение выполняется в разных потоках.
Вот код, который я написал для того же.
Вызов родительского метода:
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 (задача):
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