Optimal java threadsafe object pool

I don’t understand Java parallel library, so for the following problems I usually just write my own mutex-driven code, but I am worried that with servlet traffic, mutexes slow down the system.

The first need is that with a finite set of String keys, I need to search first, otherwise create and publish an expensive object. This implies one global mutex in a naive implementation. Is there something better?

The second need is that every expensive facility has a soft pool of equivalent workers, any of which is sufficient to perform. These workers are cheaper to create than a factory for workers, but they are still expensive and need to be combined. A naive implementation would have one mutex per factory and write the worker out of the soft cache or create one if it is not available. But with more servlet requests using the same factory (probably), this mutex will also become a point of contention.

Of course, for the two mutexes, I can minimize the time taken to synchronize, but in both cases I am looking for something better. Maybe there is a non-blocking solution for both?

Andy

+4
source share
4 answers

For the first part: instead of moving expensive objects directly to the HashMap, instead create a simple wrapper that will be cheap to create. Then you basically create an expensive object on demand in the wrappers getExpensiveObject() method - although it may possibly call creation right away if that is preferred. In any case, you need to synchronize the get method, but this can be done cheaply with a double-checked lock - in the general case, we simply replace normal reading with mutable reading and have expensive synchronization only when creating an object.

It is assumed that you are using ConcurrentHashMap views, since we need putIfAbsent or some equivalent method for this (we do not want to replace the existing expensive object with our empty shell)

There is no time to think about the second problem at the moment, maybe later.

+1
source

Take a look at this thread pool tutorial . It seems to describe what you are looking for, a workflow pool.

0
source

I need to search first, otherwise create and publish an expensive object.

There is no non-blocking solution for this. There is a non-blocking card with get and put if it is missing, but this requires that the value of the value be pre-computed, which you cannot do with an expensive object.

You might want to take a look at “Shared and parallel object pools,” which uses some of the blocking queues associated with them that can avoid a unanimous mutex conflict.

0
source

I think I have an answer after further thought:

NOTE. My answer depends on the fact that both factories are idempotent with respect to its string key, and workers are all idempotent with respect to their factory, which may not have been obvious from the question.

For the first global hash of a file based on a singleton key, I use the idea that hashmap never has deletions. Only new idempotent ones. Therefore, I use the volatile hashmap reference, and get the current map from the volatile singleton variable without a mutex. (the volatility of getting links is currently very contradictory in Java). If the card is outdated, in the sense that it does not have all the current factories, this is normal. Because if he has a factory (usually he will warm up), I have it. With only the cost of volatile receipt. If he doesn’t have one, I’ll now consult a live map to get inside the mutex for a live map. If I get the factory from the card now (unlikely), I succeeded. Otherwise, now I am doing a very expensive operation of creating a factory (outside of the mutexes). When you are done, I will return to the live map with the mutex, and because another thread is doing the same thing, it might be there now! Therefore, if a factory is present on the map, I throw away the wasted factory that I just created and use the one that was put there in front of me. Otherwise, I overlay the new factory on the map, leave the mutex and start using the factory.

I do not think it is better for this.

In softcache factory, I think I just want to use ConcurrentLinkedQueue. However, my items will be links to softreferences. Therefore, I deduce from ConcurrentLinkedQueue an object that refers to a soft link to the employee himself. The worker may have been relaxed, so I re-create the worker from the factory and re-create the soft link in the object that I got from ConcurrentLinkedQueue, and set the soft link to the employee. Thus, there is no mutex to get the worker from the factory, just checking ConcurrentLinkedQueue, and the links to the worker are soft.

0
source

Source: https://habr.com/ru/post/1389828/


All Articles