用于快速访问共享数据的单例 Bean

Singleton Bean for quick access to shared data

关于 Singleton Bean 的使用,我有几个问题。

首先让我描述一下情况。 有一个 Web 应用程序将有许多客户端发送和接收数据 to/from。其中一些数据必须保存在数据库中,但我需要其中的大部分数据在服务器上可用以便快速访问并减轻数据库的压力。

我将为共享 space 使用 Singleton Bean,这是我的问题:

  1. 如果 client_1 试图更新他在当前被 client_2 写入锁定的单例成员中的数据,那么 client_1 数据到底发生了什么?我需要为这种情况做准备,还是像堆栈一样,他的写操作将在 client_2 完成他的之后进行?

  2. 如果我使用 hashmap,哪些键将对应于各个写入客户端,将 @Lock(READ) 放在只能更新现有记录的 set 方法上是否安全而不是添加新的。在我看来,由于每个客户端只能写入自己的记录,因此无需阻止其他人同时更新自己的记录。

  1. client_1 会等待 client_2 完成然后自己更新数据

  2. hashmap 不是线程安全的您可能也有兴趣查看以下内容之一:

   private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
>       
>       private final Lock readLock = readWriteLock.readLock();
>     
>       private final Lock writeLock = readWriteLock.writeLock();
>     
>       private final List<E> list = new ArrayList<>();
>       
>       public void set(E o)
>       {
>           writeLock.lock();
>           try
>           {
>               list.add(o);
>               System.out.println("Adding element by thread"+Thread.currentThread().getName());
>               }
>           finally
>           {
>               writeLock.unlock();
>           }
>       }

(Source)

  1. EJB 单例提供对方法的同步访问。如果 client_1client_2 的同时调用 Lock.WRITE 方法,则 client_1 的调用会一直等到 client_2 完成。您还可以配置超时值以指定如果此等待时间过长,client_1 returns 一个错误。

  2. 在这种情况下,映射将用于存储引用 - 客户端可以从映射中检索其状态对象(受读锁保护),然后在不同步的情况下修改该对象全部。映射本身的更新应该受到写锁的保护(这很可能仅在您添加或删除条目时才需要)。请注意,如果您要使用任何 Java 同步原语(例如 ConcurrentHashMap),您需要声明您正在使用 bean 管理的并发 - @ConcurrencyManagement(BEAN).

同样值得注意的是,JPA 会自动为您提供缓存,因此您可能会发现添加自己的缓存不会带来太多性能优势。此外,此模型假定单个客户端不会发出并发请求 - 如果它们发出请求,您将对单个对象进行并发更新,并且需要一些额外的同步。