In Java, Change/Read String In a Multi-thread Circumstance - java

Background
An access token is used by my system to access a platform API.
I have a Thread A to update the access token every 2 min.
Then the other threads who handle front-end requests will use the access token to make API calls.
The platform who provides the access token itself has implemented some token overlap mechanism. That is, an old token will still be available for 30 seconds after a new token is generated.
Thoughts
I have an interface like below:
public interface AccessTokenService {
String fetchAccessToken();
void refreshAccessToken();
}
Apparently, the easiest and error-free way to handle it is to make these two methods synchronized. However, since the token providing platform has token overlap built-in. I don't think "synchronized" is needed to make it business right. In addition, since my system highly relies on the API calls, make the methods synchronized would result in a performance drop.
Question
My question is, how, under the hood, the JVM handle multi-thread String write/read.
Say, a string accessToken is being changed from "abc" to "def". Meanwhile, a few threads are trying to read the value of accessToken. What are the possible output of the read?
abc (possible)
def (possible)
dbc (?)
messy content in between the change (?)
null (?)

Since strings in java are immutable your reading threads can only get either to old token or the new token, but never something mixed together.
Updates to references are always atomar (here too: your reading threads can either read the old reference or the new reference, but not something mixed together).
There is only one point to observe: the field that stores the current token has to be declared as volatile, otherwise the reading threads may cache some value that they have seen.
A dummy implementation of your AccessTokenService could look like this:
public class DummyAccessTokenService implements AccessTokenService {
private volatile String currentToken = null;
#Override
public String fetchAccessToken() {
return currentToken;
}
private int tokenNumber = 0;
#Override
public void refreshAccessToken() {
currentToken = String.format("Token-%d", tokenNumber++);
}
}

Related

Java store reflected Method statically in class: Safe?

Is something like the following 'safe' in Java, and why?
public final class Utility {
private Utility() {}
private static Method sFooMethod = null;
public static void callFoo(SomeThing thing) {
try {
if(sFooMethod == null)
sFooMethod = SomeThing.class.getMethod("foo");
sFooMethod.invoke(thing);
} catch(Exception e) {} // Just for simplicity here
}
}
My rationale would be that even if another thread writes to sFooMethod in the background and the current thread sees it suddenly somewhere during execution of callFoo(), it would still just result in the same old reflective invoke of thing.foo()?
Extra question: In what ways does the following approach differ (positive/negative) from the above? Would it be preferred?
public final class Utility {
private Utility() {}
private static final Method sFooMethod;
static {
try {
sFooMethod = SomeThing.class.getMethod("foo");
} catch(Exception e) {}
}
public static void callFoo(SomeThing thing) {
try {
if(sFooMethod != null)
sFooMethod.invoke(thing);
} catch(Exception e) {}
}
}
Background update from comment:
I am writing an Android app and I need to call a method that was private until API 29, when it was made public without being changed. In an alpha release (can't use this yet) of the AndroidX core library Google provides a HandlerCompat method that uses reflection to call the private method if it is not public. So I copied Google's method into my own HandlerCompatP class for now, but I noticed that if I call it 1000 times, then the reflective lookup will occur 1000 times (I couldn't see any caching). So that got me thinking about whether there is a good way to perform the reflection once only, and only if needed.
"Don't use reflection" is not an answer here as in this case it is required, and Google themselves intended for it to happen in their compatibility library. My question is also not whether using reflection is safe and/or good practice, I'm well aware it's not good in general, but instead whether given that I am using reflection, which method would be safe/better.
The key to avoiding memory consistency errors is understanding the happens-before relationship. This relationship is simply a guarantee that memory writes by one specific statement are visible to another specific statement.
Java language specification states following:
17.4.5. Happens-before Order
Two actions can be ordered by a happens-before relationship. If one
action happens-before another, then the first is visible to and
ordered before the second.
If we have two actions x and y, we write hb(x, y) to indicate that x
happens-before y.
If x and y are actions of the same thread and x comes before y in
program order, then hb(x, y).
As, in your case, writing to and then reading from the static field are happening in same tread. So the `happens before' relation is established. So the read operation will always see effects of the write operation.
Also, all threads are going to write same data. At worse, all eligible threads will write to the variable same time. The variable will have reference to the object that got assigned last and rest of the dereferenced objects will be garbage collected.
There won't be many threads in your App which will enter the same method at once, which will cause significant performance hit due to lot of object creation. But if you want to set the variable only once then second approach is better. As static blocks are thread safe.
Is something like the following 'safe' in Java, and why?
No I would not recommend using reflections, unless you have to.
Most of the time developers design their classes in a way, so that access to a hidden field or method is never required. There will most likely be a better way to access the hidden content.
Especially hidden fields and methods could change their name, when the library they are contained in is updated. So your code could just stop working suddenly and you would not know why, since the compiler would not output any errors.
It is also faster to directly access a method or field then through reflections, because the reflections first need to search for it and the direct access don't
So don't use reflections if you don't have to
I'm not sure what your goal is -- there is probably a better way to do what you're trying to do.
The second approach, with a static initializer, is preferable because your first implementation has a race condition.

Java Event Listener return value

I am using Java8. I have an Listener that calls onSuccess when completed with a customToken.
#Override
public String getCustomToken(Person person) {
FirebaseAuth.getInstance().createCustomToken(person.getUid()).addOnSuccessListener(new OnSuccessListener<String>() {
#Override
public void onSuccess(String customToken) {
// I would like to return the customToken
}
});
return null;
}
Question
How do I get this method to return the String customToken?
Your question is intriguing, but the accepted answer unfortunately provides you with wrong means.
The problem with your question is that of API. You are trying to use callbacks in a way they are not designed to be used. A callback, by definition, is supposed to provide a means to do something asynchronously. It is more like a specification of what to do when something happens (in future). Making a synchronous method like getCustomToken() return something that is a result of an inherently asynchronous operation like onSuccess() implies a fundamental disconnect.
While dealing with callbacks, it is critical to understand the importance of continuations: taking actions when certain events of interest happen. Note that these events may not even happen. But you are specifying in the code the actions to take, if and when those events occur. Thus, continuation style is a shift from procedural style.
What adds to the data flow complexity is the syntax of the anonymous inner classes. You tend to think "oh, why can't I just return from here what onSuccess() returns? After all, the code is right here." But imagine that Java had no inner classes (and as you may know, (anonymous) inner class can easily be replaced by a class that is not an inner class). You'd have needed to do something like:
OnSuccessListener listener = new SomeImplementation();
FirebaseAuth.getInstance().createCustomToken(listener);
Now, the code that returned data (String) is gone. You can even visually reason that in this case, there is no way for your method to return a string -- it is simply not there!
So, I encourage you to think of what should happen if and when (in future) onSuccess() is called on the OnSuccessListener instance that you pass in. In other words, think twice if you really want to provide in your API, the getCustomToken() method (that returns a token string, given a Person instance).
If you absolutely must provide such a method, you
Should document that the returned token may be null (or something more meaningful like None) and that your clients must try again if they want a valid value.
Should provide a listener that updates a thread-safe container of tokens that this method reads.
Googling around, I found the Firebase documentation. This also seems to suggest taking an action on success (in a continuation style):
FirebaseAuth.getInstance().createCustomToken(uid)
.addOnSuccessListener(new OnSuccessListener<String>() {
#Override
public void onSuccess(String customToken) {
// **Send token back to client**
}
});
The other problem with trying to provide such API is the apparent complexity of the code for something trivial. The data flow has become quite complex and difficult to understand.
If blocking is acceptable to you as a solution, then perhaps you can use the Callable-Future style where you pass a Callable and then later do a get() on the Future that may block. But I am not sure if that is a good design choice here.
This would work syntactically:
final List<String> tokenContainer = new ArrayList<>();
FirebaseAuth.getInstance().createCustomToken(person.getUid()).addOnSuccessListener(new OnSuccessListener<String>() {
#Override
public void onSuccess(String customToken) {
tokenContainer.add(customToken);
}
});
return tokenContainer.get(0);
As said; this works syntactically. But if it really works would depend if the overall flow is happening in one thread; or multiple ones.
In other words: when the above code is executed in sequence, then that list should contain exactly one entry in the end. But if that callback happens on a different thread, then you would need a more complicated solution. A hackish way could be to prepend
return tokenContainer.get(0);
with
while (tokenContainer.isEmpty()) {
Thread.sleep(50);
}
return tokenContainer.get(0);
In other words: have the "outer thing" sit and wait for the callback to happen. But the more sane approach would be to instead use a field of the surrounding class.
Edit: if the above is regarded a hack or not; might depend on your context to a certain degree. The only thing that really troubles me with your code is the fact that you are creating a new listener; which gets added "somewhere" ... to stay there?! What I mean is: shouldn't there be code to unregister that listener somewhere?
The original accepted answer suggests sleeping the thread, which is a bad solution because you can't know how long the thread needs to sleep. A better solution is to use a semaphore (or similarly, a latch). After the listener gets the value, it releases a semaphore, which allows your thread to return the value, as shown below.
private final AtomicReference<String> tokenReference = new AtomicReference();
private final Semaphore semaphore = new Semaphore(0);
public String getCustomToken(Person person) {
FirebaseAuth.getInstance().createCustomToken(person.getUid()).addOnSuccessListener(customToken -> {
this.tokenReference.set(customToken);
this.sempahore.release();
});
this.semaphore.acquire();
return this.tokenReference.get();
}
Notice also that I used an AtomicReference because in order for what you asked for to be possible at all the listener must be called on a separate thread than the thread on which getCustomToken was called, and we want the value to be synchronized (I'd guess that behind the scenes Firebase is creating a thread, or this call occurs over the network). Since this.tokenReference will be overwritten, it is possible to get a newer value when getCustomToken is called more than once, which may or may not be acceptable depending on your use case.
Extract a variable into a suitable scope (class attribute or method variable)
private String customToken;
#Override
public String getCustomToken(Person person) {
FirebaseAuth.getInstance().createCustomToken(person.getUid()).addOnSuccessListener(new OnSuccessListener<String>() {
#Override
public void onSuccess(String customToken) {
this.customToken = customToken
}
});
return null;
}

Way to prioritize specific API calls with multithreads or priority queue?

In my application, my servlet(running on tomcat) takes in a doPost request, and it returns an initial value of an api call to the user for presentation and then does a ton of data analysis in the back with a lot more other api calls. The data analysis then goes into my mongodb. The problem arises when I want to start the process before the bulk api calls are finished. There are so many calls that I would need at least 20 seconds. I don't want the user to wait for 20 seconds for their initial data display, so I want the data analysis to pause to let the new request to call for that initial api for display.
Here's the general structure of my function after the doPost(async'd so this is in a Runnable). It's a bit long so I abbreviated it for easier read:
private void postMatches(ServletRequest req, ServletResponse res) {
... getting the necessary fields from the req ...
/* read in values for arrays */
String rankQueue = generateQueryStringArray("RankedQueues=", "rankedQueues", info);
String season = generateQueryStringArray("seasons=", "seasons", info);
String champion = generateQueryStringArray("championIds=", "championIds", info);
/* first api call, "return" this and then start analysis */
JSONObject recentMatches = caller.callRiotMatchHistory(region, "" + playerId);
try {
PrintWriter out = res.getWriter();
out.write((new Gson()).toJson(recentMatches));
out.close();
} catch (IOException e) {
e.printStackTrace();
}
/* use array values to send more api calls */
JSONObject matchList = caller.callRiotMatchList(playerId, region, rankQueue, season, champion);
... do a ton more api calls with the matchList's id's...
}
So one of my ideas is to
Have two threads per client.
That way, there would be one thread calling that single api call, and the other thread would be calling the rest 999 api calls. This way, the single api calling thread would just wait until another doPost from the same client would come and call the api immediately, and the bulk api calls that come with it will just be appended to the other thread. By doing this, the two threads will compute in parallel.
Have a priority queue, put the initial call on high priority
This way, every URL will be passed through the queue and I can chose the compareTo of specific URL's to be greater(maybe wrap it in a bean). However, I'm not sure how the api caller will be able to distinguish which call is which, because once the url's added into the queue it loses identity. Is there any way to fix that? I know callbacks aren't available in java, so it's kind of hard to do that.
Are either of these two ideas possible? No need for code, but it would be greatly appreciated!
PS: I'm using Jersey for API calls.
The best bet for you seems to be using the "two threads per client" solution. Or rather a variation of it.
I figure the API you're calling will have some rate-limiting in place, so that significant amounts of calls will get automatically blocked. That's problematic for you since that limit can probably be trivially reached with just a few requests you process simultaneously.
Additionally you may hit I/O-Limits rather sooner than later, depending on how timeintensive your calculations are. This means you should have an intrinsic limit for your background API calls, the initial request should be fine without any inherent limiting. As such a fixed-size ThreadPool seems to be the perfect solution. Exposing it as a static ExecutorService in your service should be the simplest solution.
As such I'd propose that you expose a static service, that takes the matchList as parameter and then "does it's thing".
It could looks something like this:
public class MatchProcessor {
private static final ExecutorService service = Executors.newFixedThreadPool(THREADS);
public static void processMatchList(final JSONObject matchList) {
service.submit(() -> runAnalysis(matchList));
}
private static void runAnalysis(final JSONObject matchList) {
//processing goes here
}
}
Sidenote: this code uses java 8, it should be simple to convert the submitted lambda into a Runnable, if you're on Java 7

How to use ThreadLocal (specifically with Servlets)?

I have a web application that is using a framework where I have to implement an interface named Plot:
interface Plot {
Image getImage();
String getTitle();
}
I know the framework calls the getImage() before the getTitle(). In some cases, I need the results from the image generation in order to create the title.
I know if I do something naive like this:
class MyNaivePlot implements Plot {
private String title;
public Plot getImage() {
title = "...";
}
public String getTitle() { return title; }
}
Then I could introduce a race condition. It seems I can fix this by using a ThreadLocal but I haven't seen enough examples to know if my solution is correct (and these sorts of things are hard to test with certainty). So here's what I've come up with:
class MyThreadLocalPlot implements Plot {
private ThreadLocal<String> title = new ThreadLocal<String>();
public Plot getImage() {
title.set("...");
}
public String getTitle() {
return title.get();
}
}
Is this sufficient? Am I using ThreadLocal correctly? Note that I only need the title to hang around long enough until it is called for by getTitle(). I don't care what it's value is after that nor before getImage() is called.
Also note that I believe the framework "long lives" the MyPlot object, and a new one isn't created for each request / thread, otherwise this would be a non-issue.
Thanks!
To directly answer your question - it sounds ok.
However, I would consider some additional points:
(1) If you have a hook for a beginning/end of request - you might want to clear the thread local at the end of each such request (e.g. if it's a servlet I'd use a filter). That's for two reasons: release it for the garbage collection, and for cases of errors (so that if the next request runs into some parsing error, it will see an empty image and not the previous user's).
(2) Make sure your framework indeed guarantees a single thread (and same machine) during those 2 requests. Perhaps also check if it's going to work on upcoming versions, and on horizontal scaling/clusters.
(3) As a side note, one might also consider other solutions - e.g. a cache (which would help you as a side effect). Obviously this requires some though as to cache size, periodical clearing/updating etc.
You code is quite right; you don't have a setter method but I guess there is a typo and instead of getImage you want to write setTitle().
threadLocal has also a remove method that you should invoke when you don't need the title attribute anymore. You could find some usage examples here and here
Before deploying a ThreadLocal based version of Plot I suggest you to check if your framework create one o or more instances; simply create a regolare class with a counter and increase the counter value in the get method; you can log it to see how the counter value changes with different calls. If you use a logging framework such as log4j or logback I suggest to put the thread name in the log so you can check how/if the counter value changes with different checks.
I also suggest you to test it with multiple clients concurrently, if you have a "serial client" you may end up using always the same server thread if you are using a dedicated test instance.

Limiting concurrent access to a method

I have a problem with limiting concurrent access to a method. I have a method MyService that can be called from many places at many times. This method must return a String, that should be updated according to some rules. For this, I have an updatedString class. Before getting the String, it makes sure that the String is updated, if not, it updates it. Many threads could read the String at the same time but ONLY ONE should renew the String at the same time if it is out of date.
public final class updatedString {
private static final String UPstring;
private static final Object lock = new Object();
public static String getUpdatedString(){
synchronized(lock){
if(stringNeedRenewal()){
renewString();
}
}
return getString();
}
...
This works fine. If I have 7 threads getting the String, it guarantees that, if necessary, ONLY one thread is updating the String.
My question is, is it a good idea to have all this static? Why if not? Is it fast? Is there a better way to do this?
I have read posts like this:
What Cases Require Synchronized Method Access in Java? which suggests that static mutable variables are not a good idea, and static classes either. But I cannot see any dead-lock in the code or a better valid solution. Only that some threads will have to wait until the String is updated (if necessary) or wait for other thread to leave the synchronized block (which causes a small delay).
If the method is not static, then I have a problem because this will not work since the synchronized method acts only for the current instance that the thread is using. Synchronized the method does not work either, it seems that the lock instance-specific and not class-specific.
The other solution could be to have a Singleton that avoids creating more than one instance and then use a single synchronized not-static class, but I do not like this solution too much.
Additional information:
stringNeedRenewal() is not too expensive although it has to read from a database. renewString() on the contrary is very expensive, and has to read from several tables on the database to finally come to an answer. The String needs arbitrary renewal, but this does not happen very often (from once per hour to once per week).
#forsvarir made me think... and I think he/she was right. return getString(); MUST be inside the synchronized method. At a first sight it looks as if it can be out of it so threads will be able to read it concurrently, but what happens if a thread stops running WHILE calling getString() and other thread partially execute renewString()? We could have this situation (assuming a single processor):
THREAD 1 starts getString(). The OS
starts copying into memory the bytes
to be returned.
THREAD 1 is stopped by the OS before finishing the copy.
THREAD 2 enters the synchronized
block and starts renewString(),
changing the original String in
memory.
THREAD 1 gets control back
and finish getString using a
corrupted String!! So it copied one
part from the old string and another
from the new one.
Having the read inside the synchronized block can make everything very slow, since threads could only access this one by one.
As #Jeremy Heiler pointed out, this is an abstract problem of a cache. If the cache is old, renew it. If not, use it. It is better more clear to picture the problem like this instead of a single String (or imagine that there are 2 strings instead of one). So what happens if someone is reading at the same time as someone is modifying the cache?
First of all, you can remove the lock and the synchronized block and simply use:
public static synchronized String getUpdatedString(){
if(stringNeedRenewal()){
renewString();
}
return getString();
}
this synchronizes on the UpdatedString.class object.
Another thing you can do is used double-checked locking to prevent unnecessary waiting. Declare the string to be volatile and:
public static String getUpdatedString(){
if(stringNeedRenewal()){
synchronized(lock) {
if(stringNeedRenewal()){
renewString();
}
}
}
return getString();
}
Then, whether to use static or not - it seems it should be static, since you want to invoke it without any particular instance.
I would suggest looking into a ReentrantReadWriteLock. (Whether or not it is performant is up to you to decide.) This way you can have many read operations occur simultaneously.
Here is the example from the documentation:
class CachedData {
Object data;
volatile boolean cacheValid;
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
// Recheck state because another thread might have acquired
// write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
rwl.writeLock().unlock(); // Unlock write, still hold read
}
use(data);
rwl.readLock().unlock();
}
}
This isn't exactly what you're after, and I'm not a Java specialist, so take this with a pinch of salt :)
Perhaps the code sample you've provided is contrived, but if not, I'm unclear what the purpose of the class is. You only want one thread to update the string to it's new value. Why? Is it to save effort (because you'd rather use the processor cycles on something else)? Is it to maintain consistentcy (once a certain point is reached, the string must be updated)?
How long is the cycle between required updates?
Looking at your code...
public final class updatedString {
private static final String UPstring;
private static final Object lock = new Object();
public static String getUpdatedString(){
synchronized(lock){
// One thread is in this block at a time
if(stringNeedRenewal()){
renewString(); // This updates the shared string?
}
}
// At this point, you're calling out to a method. I don't know what the
// method does, I'm assuming it just returns UPstring, but at this point,
// you're no longer synchronized. The string actually returned may or may
// not be the same one that was present when the thread went through the
// synchronized section hence the question, what is the purpose of the
// synchronization...
return getString(); // This returns the shared string?
}
The right locking / optimizations depend upon the reason that you're putting them in place, the likelyhood of a write being required and as Paulo has said, the cost of the operations involved.
For some situations where writes are rare, and obviously depending upon what renewString does, it may be desirable to use an optimistic write approach. Where each thread checks if a refresh is required, proceeds to perform the update on a local and then only at the end, assigns the value across to the field being read (you need to track the age of your updates if you follow this approach). This would be faster for reading, since the check for 'does the string need renewed' can be performed outside of the synchronised section. Various other approaches could be used, depending upon the individual scenario...
as long as you lock is static, everything else doesn't have to be, and things will work just as they do now

Categories