I have a class that has a getter method (among others):
public class Employee {
public EmployeeAccount getAccount() {
return this.empAccount;
}
}
The problem is that the empAccount is initialized by an async call which might return null but eventually would return the actual account.
The reason is that the async call method depends on many things and sometimes might return null as it is not ready to give the account yet. Please note that I have no control over this API.
So I was thinking of doing something like:
public class Employee {
public EmployeeAccount getAccount() {
if(this.empAccount != null) {
retrieveAccount();
}
return this.empAccount;
}
private void retrieveAccount() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
this.empAccount = getAccountFromRemoteSystem(); // <--- this is a blocking call
}
};
t.start();
}
The reason I was aiming towards this is because getAccount() is expected to be non-blocking as it is called from a UI thread.
How can I design/structure my code so that it is thread safe? Are there better constructs I can use or some other design pattern?
The answer begets a specification question. Do you specify that an instance of the Employee class is usable even if that instance's EmployeeAccount (you should perhaps rename it to Account) is not yet available?
It appears that it is a valid Employee instance if the account is not yet set up. In that case, it is important to state that in the contract of the getAccount method:
/** Returns the {#linkplain EmployeeAccount} with this instance.
It may be null, if the account is not yet set up at the time of
this call. Typically, the clients should retry if this method
returns null.
#return EmployeeAccount if it is available, null otherwise.
*/
public EmployeeAccount getAccount() {
//
}
Deferring the construction of account to a later time runs the risk of the account never getting assigned a valid, non-null value for a valid looking Employee reference. This is why there's nothing like final fields and immutable instances.
If this caveat is something you and your clients are okay with, then I'd go ahead with what you have above. Make sure that the employee field is either volatile or AtomicReference, so that the updates made to it by the background thread that retrieves the real account from a remote/async call are visible to the other threads (e.g. the UI thread that calls the getter).
Related
I want to return some value depend on some value in inner class:
public boolean rename(File file) {
new OnResultListener() {
#Override
public void onResult(AsyncResult<CharSequence> result) {
// some codes
// Here is what I want to do
if (succeed) {
// rename return true
} else {
// rename return false
}
}
}
}
You can't and it does not make sense. These are two distinct functions that may very well be called on different threads. What you have to do, if you insist on returning something, is that the "rename" function itself should receive a callback as a parameter that gets called upon success. That is, if the downstream call is asynchronous then the ones calling it should be too.
An alternative would be to have a the calling function ("rename" in this case assuming it calls the function that notifies the OnResultListener) to wait on some mutex. Then, in the nested method upon receiving a result, you set some flag and then call notify() which would wake the thread held by the wait.
I think what I'm doing is correct, but since this could blow up quite badly if not, I'd really like clarification.
The code is an example to try and express the point, sorry for any minor typos.
I have the following class
public class Components
{
public final String mVar1;
public final boolean mVar2;
public Components(String var1, boolean var2)
{
mVar1 = mVar1;
mVar2 = mVar2;
}
}
If I create a volatile instance of this class, I believe that assigning the value of this component to the address of one already created and in memory is thread safe.
public class Storage
{
public static volatile Components sComponents = null;
}
So, regardless of whether I set this variable on the main or any other thread (where a set will simply point it to an object already created, NOT create a new one), it should be thread safe, because the volatile keyword is acting on the Components reference, which will just be updated to point to the object that already exists.
So, for example
public class ThreadedClass
{
public ThreadedClass()
{
// Create an instance of Components so we have something to copy
mInitialComponents = new Components("My String", false);
// Spin off a thread
create_a_new_thread( threadEntryPoint );
}
// This function is called every frame on the main thread
public void update()
{
// If we have our components, print them out
if (Storage.sComponents != null)
{
print(sComponents.mVar1);
print(sComponents.mVar2);
}
}
private Components mInitialComponents = null;
private void threadEntryPoint()
{
// Just sleep for a bit so update gets called a few times
sleep(3000);
// Set our components
Storage.sComponents = mInitialComponents;
}
}
(In the real world code, mInitialComponents is created and accessed via a synchronized function so accessing the original object is thread safe).
So, my question is, when calling update on the main or any other thread, once Storage.sComponents has been set to the existing object in threadEntryPoint, is it simply updating the objects reference, so the object will be guaranteed to be complete whenever we check for null.
Or is it possible for some or none of the internal members to have been correctly assigned.
Thanks
Your update method is not thread safe and could throw a null pointer exception. This can be resolved by changing it to be:
// This function is called every frame on the main thread
public void update()
{
final Components components = Storage.sComponents;
// If we have our components, print them out
if (components != null)
{
print(components.mVar1);
print(components.mVar2);
}
}
The inner values within Components are safe to use as they are final. This is assuming that you do not leak references to the Components instance from within it's constructor.
It is safe to assume that if components is not null, its member variables have been initialised correctly. According to the Java virtual machine spec, any access through a reference to an object that is returned from new is guaranteed to see the fully initialized version of any final fields in that object. See the JVM spec, chapter 17.5.
I have a class that can be instantiated only once for any given thread, through the use of a ThreadLocal, for instance:
public class MyClass {
private static final ThreadLocal<MyClass> classInstance =
new ThreadLocal<MyClass>() {
#Override protected MyClass initialValue() {
return new MyClass();
}
};
private MyClass() {
}
public static MyClass getInstance() {
return classInstance.get();
}
}
Now, I want these thread-specific instances to be accessed by another thread, so I end up with that kind of solution: https://stackoverflow.com/a/5180323/1768736
This solution is to use a Map (I would go for a ConcurrentHashMap), using as key a Thread-specific ID (for instance, a Map<long, MyClass>). I was considering to use Thread.currentThread().getId() as a key (providing some mechanisms to deal with the fact that a Thread ID can be reused).
But it means that I need to expose this Thread ID, for instance:
public class MyClass {
...
public long getId() {
//return the key associated with this MyClass instance in the Map.
//in my case, this would be the ID of the Thread
}
public static MyClass getMyClass(long threadId) {
//allow a Thread to access the MyClass instance of another Thread by providing an ID,
//in my case, that would be the Thread ID
}
}
So my question is: is it a bad practice to expose the ID of a Thread (the one returned by Thread.getId()), or do I have nothing to worry about? I don't know why, but my gut tells me I shouldn't do that.
Since Thread Id cannot be used to kill the thread (directly), it is safe to use. As applications can assign thread ids at the time of creating threads, I believe its usage is only to help you debug the application when you are looking at logs, thread-dumps, etc.
Also, as this link explains, it is not hard to get list of threads that are running in JVM. As long as you are aware of the fact that thread ids can get re-used after a thread has died, and your app's logic takes care of that, you should be alright.
I assume you are concerned about mobile-code security. It wouldn't appear to be the sort of thing that would introduce a vulnerability otherwise (I.D. reuse as a very long shot).
If you are worried about mobile-code security, then you want to avoid global and thread-global state anyway. You would anyway. Carrying on regardless...
From a security point of view Maps cause problems, particularly if you use non-values such as Thread for keys. A malicious subclass can pretend to be not equal to itself, equal to a different thread or acquire a Thread through Object.equals(Object). An IdentityHashMap would be ideal here, only you probably want a WeakHashMap. (I don't know why WeakHashMap uses key equality behaviour defined in Map rather than that in IdentityHashMap. A ConcurrentWeakIdentityHashMap (a "star map") would be excellent.)
Without modifying Thread, you probably want to introduce a key object that wraps thread giving the required behaviour.
final class Key {
private final int hash;
private final WeakReference<Thread> ref;
public Key(Thread thread) {
this.hash = System.identityHashCode(thread);
this.ref = new WeakReference<Thread>();
}
#Override public int hashCode() {
return hash;
}
#Override public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Key)) return false;
Key other = (Key)obj;
Thread thread = this.ref.get();
return thread != null && thread == other.ref.get();
}
}
(You will probably want to queue references so entries can be removed.)
Thread.getAllStackStraces has a security check, so untrusted code can't get them all. Similar calls limit execution to accessible thread groups.
I hope this is going to be enough information, so here it goes. If you need more info, lemme know in the comments.
I have a class that has two inner classes. The inner classes each have two methods that call a method in the outer class. So, it looks like this:
public OuterClass {
private boolean outerMethodHasBeenCalled = false;
private void outerMethod() {
if(!outerMethodHasBeenCalled) {
// do stuff
}
outerMethodHasBeenCalled = true;
}
private FirstInnerClass {
public void someMethod() {
outerMethod();
}
}
private SecondInnerClass {
public void someOtherMethod() {
outerMethod();
}
}
}
It's important to note that:
This is for an Android app. Instances of FirstInnerClass and SecondInnerClass are passed to a WebView as a JavaScript interface, so someMethod and someOtherMethod can be called at any time, in no particular order.
I currently have a problem with the existing code (without the synchronized keyword) where outerMethod is called pretty much at the exact same time (I print out a log message, and they're timestamped to the 1000th of a second) by different objects. My app then 'does stuff' twice because outerMethodHasBeenCalled is still false when outerMethod was called. This is not okay, and it is exactly what I'm trying to prevent. My app should only 'do stuff' once and only once: the first time outerMethod is called.
It might sound like I have multiple instances of OuterClass, but rest assured that it's only one instance of OuterClass.
It's important that my app 'does stuff' only the first time outerMethod gets called (I hope that's evident by now). All subsequent calls are essentially ignored. Whichever inner class calls outerMethod first -- doesn't matter.
So, is it appropriate to use the synchronized keyword in this case?
Yup, given what you've laid out above, I'd go with:
private synchronized void outerMethod() {
...
}
Note, this will have the side-effect of blocking one of the callers until the outerMethod() completes. If that is acceptable, cool. If the intent is merely that the code in outerMethod() is run once, and it is OK for the second caller not to be delayed if the first caller is running outerMethod(), you might consider:
public OuterClass {
private AtomicBoolean outerMethodHasBeenCalled = new AtomicBoolean();
private void outerMethod() {
if (outerMethodHasBeenCalled.compareAndSet(false, true)) {
// do stuff
}
}
...
See the JavaDoc for AtomicBoolean to grok what is going on there (assuming it is available in Android's Java).
Wrap everything in outerMethod that you want to run only once in a synchronized block:
private void outerMethod() {
synchronized (this) {
if(!outerMethodHasBeenCalled) {
// do stuff
}
outerMethodHasBeenCalled = true;
}
}
That way, the first time the method is called, only one thread will be allowed into the synchronized block at a time. The first one will execute the code in the if statement, then set outerMethodHasBeenCalled to true. The other threads will see that it is true, and skip the if code.
After looking at this question, I think I want to wrap ThreadLocal to add a reset behavior.
I want to have something similar to a ThreadLocal, with a method I can call from any thread to set all the values back to the same value. So far I have this:
public class ThreadLocalFlag {
private ThreadLocal<Boolean> flag;
private List<Boolean> allValues = new ArrayList<Boolean>();
public ThreadLocalFlag() {
flag = new ThreadLocal<Boolean>() {
#Override protected Boolean initialValue() {
Boolean value = false;
allValues.add(value);
return value;
}
};
}
public boolean get() {
return flag.get();
}
public void set(Boolean value) {
flag.set(value);
}
public void setAll(Boolean value) {
for (Boolean tlValue : allValues) {
tlValue = value;
}
}
}
I'm worried that the autoboxing of the primitive may mean the copies I've stored in the list will not reference the same variables referenced by the ThreadLocal if I try to set them. I've not yet tested this code, and with something tricky like this I'm looking for some expert advice before I continue down this path.
Someone will ask "Why are you doing this?". I'm working in a framework where there are other threads that callback into my code, and I don't have references to them. Periodically I want to update the value in a ThreadLocal variable they use, so performing that update requires that the thread which uses the variable do the updating. I just need a way to notify all these threads that their ThreadLocal variable is stale.
I'm flattered that there is new criticism recently regarding this three year old question, though I feel the tone of it is a little less than professional. The solution I provided has worked without incident in production during that time. However, there are bound to be better ways to achieve the goal that prompted this question, and I invite the critics to supply an answer that is clearly better. To that end, I will try to be more clear about the problem I was trying to solve.
As I mentioned earlier, I was using a framework where multiple threads are using my code, outside my control. That framework was QuickFIX/J, and I was implementing the Application interface. That interface defines hooks for handling FIX messages, and in my usage the framework was configured to be multithreaded, so that each FIX connection to the application could be handled simultaneously.
However, the QuickFIX/J framework only uses a single instance of my implementation of that interface for all the threads. I'm not in control of how the threads get started, and each is servicing a different connection with different configuration details and other state. It was natural to let some of that state, which is frequently accessed but seldom updated, live in various ThreadLocals that load their initial value once the framework has started the thread.
Elsewhere in the organization, we had library code to allow us to register for callbacks for notification of configuration details that change at runtime. I wanted to register for that callback, and when I received it, I wanted to let all the threads know that it's time to reload the values of those ThreadLocals, as they may have changed. That callback comes from a thread I don't control, just like the QuickFIX/J threads.
My solution below uses ThreadLocalFlag (a wrapped ThreadLocal<AtomicBoolean>) solely to signal the other threads that it may be time to update their values. The callback calls setAll(true), and the QuickFIX/J threads call set(false) when they begin their update. I have downplayed the concurrency issues of the ArrayList because the only time the list is added to is during startup, and my use case was smaller than the default size of the list.
I imagine the same task could be done with other interthread communication techniques, but for what it's doing, this seemed more practical. I welcome other solutions.
Interacting with objects in a ThreadLocal across threads
I'll say up front that this is a bad idea. ThreadLocal is a special class which offers speed and thread-safety benefits if used correctly. Attempting to communicate across threads with a ThreadLocal defeats the purpose of using the class in the first place.
If you need access to an object across multiple threads there are tools designed for this purpose, notably the thread-safe collections in java.util.collect.concurrent such as ConcurrentHashMap, which you can use to replicate a ThreadLocal by using Thread objects as keys, like so:
ConcurrentHashMap<Thread, AtomicBoolean> map = new ConcurrentHashMap<>();
// pass map to threads, let them do work, using Thread.currentThread() as the key
// Update all known thread's flags
for(AtomicBoolean b : map.values()) {
b.set(true);
}
Clearer, more concise, and avoids using ThreadLocal in a way it's simply not designed for.
Notifying threads that their data is stale
I just need a way to notify all these threads that their ThreadLocal variable is stale.
If your goal is simply to notify other threads that something has changed you don't need a ThreadLocal at all. Simply use a single AtomicBoolean and share it with all your tasks, just like you would your ThreadLocal<AtomicBoolean>. As the name implies updates to an AtomicBoolean are atomic and visible cross-threads. Even better would be to use a real synchronization aid such as CyclicBarrier or Phaser, but for simple use cases there's no harm in just using an AtomicBoolean.
Creating an updatable "ThreadLocal"
All of that said, if you really want to implement a globally update-able ThreadLocal your implementation is broken. The fact that you haven't run into issues with it is only a coincidence and future refactoring may well introduce hard-to-diagnose bugs or crashes. That it "has worked without incident" only means your tests are incomplete.
First and foremost, an ArrayList is not thread-safe. You simply cannot use it (without external synchronization) when multiple threads may interact with it, even if they will do so at different times. That you aren't seeing any issues now is just a coincidence.
Storing the objects as a List prevents us from removing stale values. If you call ThreadLocal.set() it will append to your list without removing the previous value, which introduces both a memory leak and the potential for unexpected side-effects if you anticipated these objects becoming unreachable once the thread terminated, as is usually the case with ThreadLocal instances. Your use case avoids this issue by coincidence, but there's still no need to use a List.
Here is an implementation of an IterableThreadLocal which safely stores and updates all existing instances of the ThreadLocal's values, and works for any type you choose to use:
import java.util.Iterator;
import java.util.concurrent.ConcurrentMap;
import com.google.common.collect.MapMaker;
/**
* Class extends ThreadLocal to enable user to iterate over all objects
* held by the ThreadLocal instance. Note that this is inherently not
* thread-safe, and violates both the contract of ThreadLocal and much
* of the benefit of using a ThreadLocal object. This class incurs all
* the overhead of a ConcurrentHashMap, perhaps you would prefer to
* simply use a ConcurrentHashMap directly instead?
*
* If you do really want to use this class, be wary of its iterator.
* While it is as threadsafe as ConcurrentHashMap's iterator, it cannot
* guarantee that all existing objects in the ThreadLocal are available
* to the iterator, and it cannot prevent you from doing dangerous
* things with the returned values. If the returned values are not
* properly thread-safe, you will introduce issues.
*/
public class IterableThreadLocal<T> extends ThreadLocal<T>
implements Iterable<T> {
private final ConcurrentMap<Thread,T> map;
public IterableThreadLocal() {
map = new MapMaker().weakKeys().makeMap();
}
#Override
public T get() {
T val = super.get();
map.putIfAbsent(Thread.currentThread(), val);
return val;
}
#Override
public void set(T value) {
map.put(Thread.currentThread(), value);
super.set(value);
}
/**
* Note that this method fundamentally violates the contract of
* ThreadLocal, and exposes all objects to the calling thread.
* Use with extreme caution, and preferably only when you know
* no other threads will be modifying / using their ThreadLocal
* references anymore.
*/
#Override
public Iterator<T> iterator() {
return map.values().iterator();
}
}
As you can hopefully see this is little more than a wrapper around a ConcurrentHashMap, and incurs all the same overhead as using one directly, but hidden in the implementation of a ThreadLocal, which users generally expect to be fast and thread-safe. I implemented it for demonstration purposes, but I really cannot recommend using it in any setting.
It won't be a good idea to do that since the whole point of thread local storage is, well, thread locality of the value it contains - i.e. that you can be sure that no other thread than your own thread can touch the value. If other threads could touch your thread local value, it won't be "thread local" anymore and that will break the memory model contract of thread local storage.
Either you have to use something other than ThreadLocal (e.g. a ConcurrentHashMap) to store the value, or you need to find a way to schedule an update on the threads in question.
You could use google guava's map maker to create a static final ConcurrentWeakReferenceIdentityHashmap with the following type: Map<Thread, Map<String, Object>> where the second map is a ConcurrentHashMap. That way you'd be pretty close to ThreadLocal except that you can iterate through the map.
I'm disappointed in the quality of the answers received for this question; I have found my own solution.
I wrote my test case today, and found the only issue with the code in my question is the Boolean. Boolean is not mutable, so my list of references wasn't doing me any good. I had a look at this question, and changed my code to use AtomicBoolean, and now everything works as expected.
public class ThreadLocalFlag {
private ThreadLocal<AtomicBoolean> flag;
private List<AtomicBoolean> allValues = new ArrayList<AtomicBoolean>();
public ThreadLocalFlag() {
flag = new ThreadLocal<AtomicBoolean>() {
#Override protected AtomicBoolean initialValue() {
AtomicBoolean value = new AtomicBoolean();
allValues.add(value);
return value;
}
};
}
public boolean get() {
return flag.get().get();
}
public void set(boolean value) {
flag.get().set(value);
}
public void setAll(boolean value) {
for (AtomicBoolean tlValue : allValues) {
tlValue.set(value);
}
}
}
Test case:
public class ThreadLocalFlagTest {
private static ThreadLocalFlag flag = new ThreadLocalFlag();
private static boolean runThread = true;
#AfterClass
public static void tearDownOnce() throws Exception {
runThread = false;
flag = null;
}
/**
* #throws Exception if there is any issue with the test
*/
#Test
public void testSetAll() throws Exception {
startThread("ThreadLocalFlagTest-1", false);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
//ignore
}
startThread("ThreadLocalFlagTest-2", true);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
//ignore
}
startThread("ThreadLocalFlagTest-3", false);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
//ignore
}
startThread("ThreadLocalFlagTest-4", true);
try {
Thread.sleep(8000L); //watch the alternating values
} catch (InterruptedException e) {
//ignore
}
flag.setAll(true);
try {
Thread.sleep(8000L); //watch the true values
} catch (InterruptedException e) {
//ignore
}
flag.setAll(false);
try {
Thread.sleep(8000L); //watch the false values
} catch (InterruptedException e) {
//ignore
}
}
private void startThread(String name, boolean value) {
Thread t = new Thread(new RunnableCode(value));
t.setName(name);
t.start();
}
class RunnableCode implements Runnable {
private boolean initialValue;
RunnableCode(boolean value) {
initialValue = value;
}
#Override
public void run() {
flag.set(initialValue);
while (runThread) {
System.out.println(Thread.currentThread().getName() + ": " + flag.get());
try {
Thread.sleep(4000L);
} catch (InterruptedException e) {
//ignore
}
}
}
}
}