Checklist for thread safe java on appengine

My java appengine project does not save any state between requests except for the following uses of Memcache:

  • Objectify uses memcache to cache data. Datastore gets
  • I use memcache as a way to batch clean up after multiple requests (e.g. if (the memcache doesn't think a cleanup task is already running) schedule another cleanup task ).

I have no global / static references to any objects except:

  • The current authenticated user is stored in the static ThreadLocal<User> object. This means that each request will receive its own copy of the User, right?
  • I have a class that handles all data manipulations, and the instance is stored as a kind of global variable in the static DataCoordinator object.

What do I need to make my code thread safe? Do I need to throw the synchronized in every method declaration in my DataCoordinator implementation, since multiple threads can access it? Is it true that the ThreadLocal<User> object will always create a separate User object for each thread so that each request is authenticated separately?

I am a complete newbie to thread safe thinking. What should I read?

Thanks for any help and sorry for the lack of specifics.

+6
source share
2 answers

First of all, you should be aware that the application engine can replicate your application on multiple servers. This means that your static variables will be unique on only one server. Thus, your DataCoordinator will coordinate only access to data on one server. Therefore, if you need common data for all the servers on which your application is running, you should always use the data store for this (or in some cases the gae HTTP session mechanism).

Regarding thread safety DataCoordinator : you only need to synchronize the methods of this coordinator, if these methods are not implemented by a safe thread. For example, you do not need to synchronize any methods that do not have access to any instances / static data, but simply retrieve data from the data warehouse. If access methods to shared instances / static data that change (are also recorded at the same time), you can synchronize on a special monitor to access the data in most cases instead of synchronization on the entire coordinator.

Regarding your ThreadLocal used to store the authentication token: you can do it (I do this, for example, to authenticate the user in gae for GWT factory requests), and yes, each thread will have its own variable value for how long you set it for this flow. This means that it is better to make sure that the variable is set for each thread, and we recommend using try - finally -block after setting it, which ultimately deletes the authentication data after use. What for? Worse, it could otherwise have happened that the thread belonging to the request of user B still has the authentication token of user A. This is because the threads used on the application server are usually combined between requests and not cleared and recreated.

I can not say anything about memcache since I did not use it.

As a rule, you should know that any web requests (servlet / JSP / ...) can be processed simultaneously by the server. Thus, any modified shared resources that these threads access must be synchronized or implemented in thread safe mode.

Perhaps http://download.oracle.com/javase/tutorial/essential/concurrency/ is a good starting point to read.

+7
source

If you have singleton classes, then only one instance will be created / used by your code on the created virtual machine / instance.

Link to this singleton can be obtained from:
- two consecutive requests made one after another, which are served by the same instance (depending on your settings, how long they remain, or if the reserved instance is running)
- two parallel requests executed in separate threads in one instance, if you have thread safe value true.

I wrote and tested the code to prove it to myself, and deployed and tested it. If the code in one request uses singleton to change one of its member variables, then it changes for another request that runs in parallel.

Everything is logical if you find out the lifetime of the virtual machine and how many threads (only 1 or several) are used to serve incoming requests.

In addition, system variables can be changed by code in one request and read in another ... the second way the two parallel requests / threads interact.

For more on this, see your GAE / J multithreading blog post here:
http://devcon5.blogspot.com/2012/09/threadsafe-in-appengine-gaej.html

+3
source

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


All Articles