gpt4 book ai didi

java - 使用嵌入式 ObjectDB 进行多线程处理

转载 作者:太空宇宙 更新时间:2023-11-04 14:55:51 25 4
gpt4 key购买 nike

我需要一个带有 ObjectDB 的原子计数器,但以下代码无法按我的预期工作:

    final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test.odb");
EntityManager em = emf.createEntityManager();
Point p = new Point(0, 0);
em.getTransaction().begin();
em.persist(p);
em.getTransaction().commit();
em.close();
final CountDownLatch l = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//Query q = em.createQuery("UPDATE Point SET x = x + 1");
Query query = em.createQuery("UPDATE Point SET x = x + 1");
query.executeUpdate();
em.getTransaction().commit();
em.close();
l.countDown();
}
});
t.start();
}
l.await();
em = emf.createEntityManager();
TypedQuery<Point> myquery = em.createQuery("SELECT p from Point p", Point.class);
List<Point> results = myquery.getResultList();
System.out.println("X coordiate is: " + results.get(0).getX());
em.close();

它应该打印出 X 坐标是 100。但实际上,它没有。

我的代码有什么问题吗?

最佳答案

您可以通过以下方式之一修复代码:

同步您的更新查询,以便它们将按顺序执行,而不是同时执行:

synchronized (lock) {
em.createQuery("UPDATE Point SET x = x + 1").executeUpdate();
}

你的锁对象必须是一个被所有线程共享的对象。

或者,通过设置悲观锁定超时来使用 ObjectDB/JPA 锁定,例如作者:

Map<String, Integer> properties =
Collections.singletonMap("javax.persistence.lock.timeout", 1000);
EntityManagerFactory emf =
Persistence.createEntityManagerFactory(
"objectdb:$objectdb/db/test.tmp;drop", properties);

然后用带锁和更新的检索替换 UPDATE 查询:

Point point = em.find(Point.class, 1, LockModeType.PESSIMISTIC_WRITE);
point.setX(point.getX() + 1);

关于java - 使用嵌入式 ObjectDB 进行多线程处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23213969/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com