in java how to replace an immutable object - java

how
lets say i have this class
#ImmutableWannabe
public class ConfigurationHolder {
#ImmutableButHowToMakeSureNoTwoThreadsOverrideOneEachOtherWhenReplacingReference
private Map<System, Configuration> mySysConfig = ImmutableMap.builder<>getSomeConfigurations....build();
ConfigurationHolder(copy constructor) {
mySysConfig = ImmutableMap.builder().of(inputSysConfig);
}
}
Now lets say one of the systems configuration has updated and i need to update this map of however I need to do it in a thread safe way. which means if two threads try to update the same configuration of same system data should be consistent and they should not override one each other.
How did immutability help me here? As far as i can see i still need to do locking if yes how to do it properly?
so my general question is: isn't it the case that any immutableObject which can change over system time will cause us to need to lock the code that will need to change its ImmutableObjectHolder? I don't get it...
can someone please give a proper example of an ImmutableMap + Holder for that Map + proper "client" code that knows to update this ImmutableMapHolder with updates to the internal Map?
thanks

Assuming your map is some instance variable, the simplest way it to make it volatile. Alternatively, make a getter and setter for it and make them synchronized. i.e., use standard techniques. And note that this won't help if the client tries to be clever and cache the value in a local variable. (I've bitten myself with this bug a couple of times.)
I guess as an alternative you could setup some MyImmutableChanged event/listener.
And, you are correct, immutability doesn't solve every threading problem.

Related

Know when value of any variable defined inside the class is changed

I have defined a class which acts like a model/pojo. The class has many keys/variable. I have implemented custom solution for storing the POJO on disk for future uses. Now what I want to do is that whenever any value in the class/POJO is changed, I should call a method which sync the fresh changes with file on disk.
I know I can define setter for each variable. But it's quite tedious to do for 100s of direct and sub fields, and even if I define setter for each field, I have to call sync function from all the setters.
What I need is single proxy setter or interceptor for all change pushes to variables in class.
I am using this in an android application, so whenever the user enters new details in his/her account I have to store those details at that specific instance of time for preventing the data loss. I am using GSON for serialising and de-serialising.
Sorry for using vague terminologies, never been to college :|.
The easiest solution is indeed to use a setter. You only have to create one for each field you want to monitor, and most IDEs generate them for you or you can use something like Koloboke, so it being tedious isn't really an argument.
A proxy class or reflection would also be possible, but that is pretty hacky. Another way would be an asynchronous watcher/worker that checks for changes in you POJO instances, but even that seems unnecessarily complicated.
Apart from that you might need to rethink your POJOs structure if it has that many fields.
The problem with persisting(in your case writting to a disk) entity on each property update is that most of the updates are modifying more then one property. So in case you have a code like this:
entity.setA(avalue);
entity.setb(bvalue);
entity.setc(cvalue);
You would write it to the disk 3 times, which is probably not a best way, as it takes more resources, and 2 out of 3 writes are unnecessary.
There are several ways to deal with it. Imagine you have some service for saving this data to a disk, lets name it entityRepository. So one option is manually call this entityRepository each time you want to save/update your entity. It seems to be very uncomfortable, comparing to calling this automatically on setter call, however, this approach clearly shows you when and why your entity is persisted/updated, in your approach it's unclear, and can lead to some problems future problems and mistakes, for example, in future you will decide that you now need to update one of the properties without immideately persisting, then it appears that you will need 2 setter, one with update, and one without...
Another way is to add version property, and when its setter is called inside this setter call entityRepository.save(this).
The other way is to look at AOP, however anyway I don't recommend persist entity on any change, without having control over it.
You are talking about data binding. There is no built-in way for that so you have indeed to sync it yourself. Look into How to Write a Property Change Listener. There are also lots of other approaches to this, but as said no built-in way.

Is it necessary to synchronize a factory method that returns a new instance of a class in java

Today i was asked to write up a factory to get a new instance of a class.
I did this quite easily.
One of my all knowing colleagues looked at my code and told me to synchronize the method that does this.
I asked him why and he replied that is the right thing to do. (offered no explanation when asked) I did not do it as i believe since i'm not manipulating the state of the object, i don't have to synchronize it.
I just want to clarify whether i was right. If i was wrong, can someone explain why it is necessary to synchronize.
eg
private static Map<String, IProduct> products = new HashMap<String, IProduct>();
public IProduct getInstance(code){
return products.get(code).create();
}
Edit based on comments :
I can't give the full code as I don't have access to it now. I will do it when I get back to work.
products is a Map<String, IProduct>
create() is a method on the class implementing IProduct. This method just returns a new instance of the implementing class.
the instance put into the static map is only to be used to 'new' up an instance of Product.
I'm going to guess that products is a Map and that it is not synchronized (either by its implementation or via Collections.syncronizedMap()). If whatever is stored in products is mutable, then it is possible that something else is going to be working with products while you are using get() and this could cause some issue.
Specifically, if whatever the class is that has a create() method is mutable, then in a parallel environment, some other thread could mutate the value retrieved from products after get() and before create(), which could cause problems (for instance, if create() can only be called a set number of times).
That said, you should press your colleague as to why they want you to synchronize the method. They should have a specific reason, and if they can't explain it to you, their reason either isn't good enough or they don't understand it enough.
If we synchronize the factory method,we will make sure while one thread retrieves a new instance,any other thread does not do the same.Instead any parallel thread would wait for its turn and get the already created instance.

Test the behaviour of concurrent code

I have an object which after receiving some message changes state asynchronously (an internal thread changes the state). After the state changed I want to test some behavior.
So basically I need to do something like:
Create object
Send message to object
Wait for state to change
Test behavior
However, the state is private and not exposed.
Is there an elegant solution to this that does not require exposing the state?
And if not - is it reasonable to require changing the main code just to make it more testable?
if the state is private, it is only accessible within its own class (https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html) meaning that you will not be able to get the state from your newly created object without modifying the class.
Now, whether it is reasonable to modify the class in order to do some testing is up to several factors:
How many people working on that code?
How many people already using a previous version of that code?
Integrity issues that you would face if you change the state variable to public and add a getter method.
etc.
So of course I can't tell you if it is reasonable or not without knowing in detail the organization of your software.
I hope this short answer helps you at least to clarify the problem.
You can access the relevant private fields with Reflection assuming you have the permissions to do so.
Foo bar = new Foo();
bar.setValue(true);
Field field = Foo.class.getDeclaredField("value");
field.setAccessible(true);
Object value = field.get(bar);
That will get the value stored in a private variable in the class.
This is pretty ugly and you probably shouldn't do it but if you really need to avoid altering the class you're testing with then it should do the trick.

Is it possible to manage concurrency writing with a single Property file?

I'm using Properties in my code and I'm curious about multiple access.
I'm in the following case :
public Class MClass{
private static Properties dicoCategories = new Properties(myPropertyFile);
public void changeProperties(){
// changing properties and updating the file
}
}
MyClass is instanciated multiple times and each instance can modify the property file
. I guess I could manage this concurrency using temp files and locks, but I would prefer to use an already existing function. However, I found none. My question is : does the Property class manages concurrency a special way, or is there a multi-users equivalent ?
Although the Properties file is thread-safe, if you modify it using multiple invocations you still need to ensure thread safety. e.g.
properties.set(name, value);
is thread-safe, but
if (properties.get(name) == null) {
properties.set(name, value);
}
is not thread-safe without additional guards, and you should synchronise around such sequences.
It's not clear from your question whether your real issue is with multiple processes accessing this properties file, and if that is the case, then perhaps file locking is appropriate. See this question/answer for more info.
According to the documentation:
This class is thread-safe: multiple threads can share a single Properties object without the need for external synchronization.
According to the Java API, it is thread-safe:
http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html
This would mean that you're OK making changes from different threads concurrently. However I would run a simple concurrency test to be 100% sure. You can also go into the source file and see how Java handles it internally...
As per Java documention
This class is thread-safe: multiple threads can share
a single Properties object without the need for external synchronization
So, answer is that you can use the Properties instance in multi-threaded environment.
What you need to keep in mind is that if the updates to Properties are very frequently done, then, it is possible that your application can become slow due to implicit synchronization within Properties. However, if it is once in a while, then you should be fine.

java - how to persist variable in JVM

I have an odd situation where i want to be able to be able to persist a variable in memory.. like a global variable I can pin in the JVM.
Is this possible? I remember doing something similar in college, but can't find it by googling. I have a logic problem that has some artificial constraints that make this the best possible solution.
EDIT 1:
I will need to update the value of the variable.
EDIT 2 :
I appreciate the responses guys. I'm a .net programmer and hadn't used java since college. Thanks again.
Yes, using a static field:
public class GlobalVariableHolder {
public static int globalVariable;
}
Note, however, that this is considered a bad practice and can lead to unexpected results that are hard to debug. The way to not use a global variable is to pass it around as an argument or methods where you need it.
If you are still sure you need this, in order to guard yourself as much as possible, use synchronization. Even better, if the variable is going to be primitive (int, long, etc), you can use AtomicInteger's getAndAdd() or addAndGet() method.
Usually you will end up storing these things in some kind of a global class--a class that is accessible from anywhere and has a controlled number of instances.
Singletons are commonly used for this. If you look up the pattern for a singleton and store your variable in that singleton (add a setter and a getter) you are on your way.
Doing this (as opposed to a public static variable) will give you some level of access control and traceability--for instance you can put debug statements in the getter if you find you are getting unpredictable results.
In the long run setters and getters and singletons are all bad code smells but no where near as bad as a settable public variable.
Later you may want to move the code that manipulates that variable into the singleton object and possibly convert the singleton to something you can fetch via IOC, but having a singleton is a much better place to start than with a public static.
Do you mean something that will exist across multiple invocations of java.exe, or do you mean a single variable that will be the same location in memory regardless of which thread within java.exe access it? Or do you mean a variable that can only be accessed if you're using JRockit? Or maybe just the JVM on your dev machine, but not on another system?
In the first case, you'd need another way to store it, like a config file.
In the second case, like Bozho says, use the static keyword.
In the third case, you'd probably need to use the System class and determine the JVM manufacturer (Assuming that's available from System - I'm not sure off the top of my head, and you'll learn more by looking up the API yourself).
In the fourth case, you're pretty much back to a config file.
Its not going to win any awards but this should work:
package mypackage;
public class MyGlobal {
public static String MY_GLOBAL_VAR = "my variable";
}
Any class within that JVM instance would be able to access MyGlobal.MY_GLOBAL_VAR.
Updated to allow update.

Categories

Resources