Reputation: 10695
I have a search box in the header of my web application and use autocomplete to help users find books by author's name or book's title. On user input, oninput()
function calls servlet FindBooks
through ajax
. FindBooks
servlet calls static method suggest()
of class SuggestionBook
which returns array of books matching input string.
FindBooks.java
JSONArray books = SuggestionBook.suggest(inputString);
out.print(books);
SuggestionBook.java
private static boolean isTernaryEmpty = true;
private static Ternary ternary;
private static void fillTernary() {
// fills ternary search tree with data.
isTernaryEmpty = false;
}
public static JSONArray suggest(String searchString) {
if(isTernaryEmpty) {
fillTernary();
}
return ternary.find(searchString);
}
I have used static
methods in class SuggestionBook.java
, so as to avoid loading data for each session of application. So it will be loaded only once and then can be shared by different sessions. But since there is only one copy of static method and all sessions use the same static
method to fetch data. Do they have to wait while some other session is using the method or it can be accessed simultaneously by all sessions ? If Yes, does it affect the performance of the application. If No, how this concurrent access of a single copy is managed by JVM ? Lastly, as per my understanding data will stay in the memory as long as class SuggestionBook
is not garbage collected. Is it a right approach to use data structures as class variables
than instance variables
, as they will block available memory for longer time.
Upvotes: 6
Views: 5263
Reputation: 4192
Do they have to wait while some other session is using the method or it can be accessed simultaneously by all sessions ?
No they don't have to wait and yes they can be accessed simultaneously.
Accessing the same object from multiple sessions simultaneously can be a problem but does not have to be. If for example two sessions perform simultaneous access to an object without changing its state that would be fine. If they do change the state and the state transition involves instable intermediate states a problem could arise.
If two threads are running the same method at the same time they will both have their code pointers pointing at that method and have their own copies of arguments and local variables on their stacks. They will only interfere with each other if the things on their stacks point to the same objects on the heap.
If Yes, does it affect the performance of the application. If No, how this concurrent access of a single copy is managed by JVM ?
Memory in java is split up into two kinds - the heap and the stacks. The heap is where all the objects live and the stacks are where the threads do their work. Each thread has its own stack and can't access each others stacks. Each thread also has a pointer into the code which points to the bit of code they're currently running.When a thread starts running a new method it saves the arguments and local variables in that method on its own stack. Some of these values might be pointers to objects on the heap.
Lastly, as per my understanding data will stay in the memory as long as class SuggestionBook is not garbage collected. Is it a right approach to use data structures as class variables than instance variables, as they will block available memory for longer time.
Since you're using servlet, a single instance of servlet is created only once on webapp's startup and shared among all requests. Static or not, every class/instance variable is going to be shared among all requests/sessions. There will be only a single instance of the Servlet, and an instance variable will act like a static variable. Therefore, rather than requiring people to know about the single instance (since many people do not) by making the variable static rather than instance, it removes any confusion in the usage. Therefore the intent of the variable is clearer and less likely to be misunderstood. So yeah its is not a bad approach by usability.
Upvotes: 5
Reputation: 329
You can make suggest method as synchronized and it will work. As only the first called will fill the data in tree and the subsequent calls just read it.
But if you synchronize suggest method, every thread that calls suggest will be synchronized and this is unnecessary since the first call has already filled the tree.
Solution 1) Create a static block and initialize the tree in that. So that way the tree is initialized as soon as the class is loaded.
Solution 2) make "fillTernary" method as synchronized and inside the method initialize the tree only if it is not initialised i.e if(isTernaryEmpty). Please note that the if condition is required in both the methods which is to prevent multiple threads from initializing at the same time.
Upvotes: 0