阻止来自相同或不同会话的线程执行两次相同的记录

时间:2014-07-14 18:36:52

标签: java multithreading asynchronous synchronization thread-safety

我的项目使用Hibernate,Spring,Executor框架和Quartz。我正在尝试编写一个方法,该方法不应该由相同或不同会话中的线程执行两次相同的记录。以下是我要完成的任务:

第1节:

T1 (2) 
T2 (15)
T3 (2) // should not execute as already executed by previous thread

第二节:

T1 (14)
T2 (2) // should not execute as executed in different session
T3 (10)

我无法控制执行中的记录。我需要在我的代码中确保重复的记录不会被执行多次。

现在我计划在数据库中有一个状态表,并跟踪已执行或当前正在执行的记录。有没有更好的方法来实现这个目标?

(Q1)有没有办法从不同的会话中获取线程的状态(可能使用可调用/未来)?

(Q2)我可以在不同会话的线程之间共享锁定吗?我知道一种方法可以通过应用程序级上下文来实现(这是唯一的方法吗?)

谢谢!

2 个答案:

答案 0 :(得分:0)

使用AtomicBoolean executed = new AtomicBoolean(false);作为后卫,

if(!executed.getAndSet(true)) {
    // proceed
}

您自己认为这是线程安全的无锁模式。

答案 1 :(得分:0)

正如您所引用的Spring,任何spring单例bean都可以包含可以使用(或可以自己使用)进行全局同步的对象。您只需将其注入需要此类同步的任何bean中。

只要您的应用程序在单个机器上的单个tomcat上执行即可。如果您在多个服务器上使用(或计划使用)负载平衡,则只能依赖数据库锁。

在数据库中存储更新记录的跟踪总是安全的,因为您可以在处理记录的同一事务中执行此操作。因此,即使在最坏情况下,例如硬件掉落,停电等,也能保证一致性。

如果您的要求较少,并且只希望确保单个服务器上单个应用程序运行的一致性,则可以使用具有同步方法的单例bean。