关于Singleton Bean的使用,我有几个问题。
首先让我来描述一下情况。 这是一个Web应用程序,它将有许多客户端向/从它发送和接收数据。其中一些数据必须保存在数据库中,但我需要在服务器上提供大部分数据,以便快速访问并消除数据库的压力。
我将使用Singleton Bean作为共享空间,这是我的问题:
如果client_1尝试更新其当前由client_2写入LOCKED的单例成员中的数据,那么client_1数据究竟会发生什么?我是不是想要这样的情况,或者它就像一个堆栈,他的写操作将在client_2完成后发生?
如果我使用hashmap,哪些密钥对应于单个写入客户端,那么在@Lock(READ)
方法上放置set
是安全的,这种方法只能更新现有记录而不能添加新记录那些。我看待它的方式,因为每个客户只能写他自己的记录,所以不需要阻止其他人同时更新他们自己的记录。
答案 0 :(得分:0)
client_1将等待client_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();
> }
> }
答案 1 :(得分:0)
(Source)
EJB单例提供对方法的同步访问。如果client_1
在Lock.WRITE
的同时调用client_2
方法,则client_1
的调用将等待client_2
完成。您还可以配置超时值,以指定如果此等待时间过长,client_1
将返回错误。
在这种情况下,映射将用于存储引用 - 客户端可以从映射中检索其状态对象(受读锁保护),然后根本不修改该对象。对映射本身的更新应受写锁保护(这可能仅在添加或删除条目时才需要)。请注意,如果您要使用任何Java同步原语(例如ConcurrentHashMap
),则需要声明您正在使用bean管理的并发 - @ConcurrencyManagement(BEAN)
。
值得注意的是,JPA会自动为您提供缓存,因此您可能会发现添加自己的缓存并不能提供很多性能优势。此外,此模型假设单个客户端不会发出并发请求 - 如果这样做,您将对单个对象进行并发更新,并且需要一些额外的同步。