コードを最適化しようとしていて、時間のかかる操作を行うスレッドを生成したいと考えています。その最適化の実装中に、私は頭がおかしくなるような問題に遭遇しました。問題を単純化し、その特定の問題のテスト ケースを作成しました: (SpringJUnit4ClassRunner を使用しているため、testCRUD メソッドの開始時にトランザクションが適切に開始されます)
スレッドで foundParent が null である理由を誰かが理解するのを手伝ってくれますか?
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();
}
}
=============================編集=================== =============== コメントの 1 つの提案に従って、スレッドを生成する threadManager Bean を作成しました。threadManager のコードは次のとおりです。
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();
}
}
残念ながら、これも機能しません!!! :-(