gpt4 book ai didi

multithreading - Spring中的线程

转载 作者:行者123 更新时间:2023-12-03 13:16:04 27 4
gpt4 key购买 nike

我正在尝试在我的代码中进行一些优化,并希望生成一个线程来执行耗时的操作。在实现该优化的过程中,我遇到了一个让我发疯的问题。我简化了问题并为该特定问题创建了一个测试用例:(我正在使用 SpringJUnit4ClassRunner 因此事务在 testCRUD 方法的开头正确启动)

有人可以帮我理解为什么 foundParent 在线程中为空吗?

private Semaphore sema = new Semaphore(0, false);
private long parentId;

@Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);

parentDao.flush();
}

(new Thread(
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!

System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
})).start();

try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

==============================编辑==================== ================
根据一个评论建议,我创建了一个产生线程的 threadManager bean。下面是线程管理器的代码:
public class ThreadManager {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void executeTask(String Name, Runnable task) {
(new Thread(task, Name)).start();
}
}

然后在之前的测试中,我没有手动盯着线程,而是将它发布在线程管理器中,如下所示:
@Autowired private ParentDao parentDao;
@Autowired private ThreadManager threadManager;

private Semaphore sema = new Semaphore(0, false);
private long parentId;

@Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);

parentDao.flush();
}

threadManager.executeTask("BG processing...",
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!

System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
});

try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

不幸的是,这也不起作用! :-(

最佳答案

事务上下文绑定(bind)到线程。因此,衍生线程中的代码不会在与初始线程中的代码相同的事务上下文中运行。因此,由于事务隔离(ACID 中的 I),生成的线程看不到初始线程的事务在数据库中插入的内容。

关于multithreading - Spring中的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19748019/

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