简体   繁体   中英

How can I ensure data consistency if a setter value must be written into a file?

I am using Preferences to store application settings. My java class reads the settings at program start and then the data is available with simple getters for other classes.

Now I also want to implement setters because the user can change some Preferences in the program and therefore calling a setter from another java class is an easy method to change the preferences.

If I change a value in my Preferences, how can I ensure, that the data in the Preferences and in the class are consistent? Should I just store the data within the setter in the runtime object and in the Preferences?

And most importantly: How can I ensure, that no getter is called, before the data is written into the preferences? How do I need to synchronize them?

Here is just a really simple example to display the issue:

private static final Preferences PREFERENCES = //here are valid preferences
private static final String KEY = //Some path to the attribute

private static PrefManager prefManager = new PrefManager();

private String serverIP;

private PrefManager() {
    this.serverIP = PREFERENCES.get(KEY, "");
}


public static void setServerIP(String serverIP) {
    // How do I synchronize the PREFERENCE object and this setter to prevent getter
    // calls between put and = call here?
    PREFERENCES.put(KEY, serverIP);
    prefManager.serverIP = serverIP;
}

In terms of solving your race condition, you can create your own Preferences extension and add synchronized to set and get. There are two ways to create a preference extension: use a map internally and copy all key - values there, or create a facade.

In terms of how do you keep your application consistent: The answer to this is the Controller piece of MVC

Example of facade

I've copied all of the methods from Preferences and added them here. You can see that the constructor takes a Preferences parameter, which is going to be the reference implementing all methods in this facade (see the first two methods absolutePath() and addNodeChangeListener(...) for examples of how this should be implemented) Also note that the methods put and get have been synchronized. So if any thread is calling put, any other thread calling get will wait until put is done. (You may want to add synchronized to other methods as well)

===================

public class MyPrefsFacade extends Preferences {
    private Preferences p;

    public MyPrefsFacade(Preferences prefs) {
      p = prefs;
    }

    public String   absolutePath() { return p.absolutePath(); }
    public void addNodeChangeListener(NodeChangeListener ncl) { p.addNodeChangeListener(ncl); }
    public void addPreferenceChangeListener(PreferenceChangeListener pcl)
    public String[] childrenNames()
    public void clear()
    public void exportNode(OutputStream os)
    public void exportSubtree(OutputStream os)
    public void flush()
    public synchronized String  get(String key, String def)
    public boolean  getBoolean(String key, boolean def)
    public byte[]   getByteArray(String key, byte[] def)
    public double   getDouble(String key, double def)
    public float    getFloat(String key, float def)
    public int  getInt(String key, int def)
    public long getLong(String key, long def)
    public boolean  isUserNode()
    public String[] keys()
    public String   name()
    public Preferences  node(String pathName)
    public boolean  nodeExists(String pathName)
    public Preferences  parent()
    public synchronized void    put(String key, String value)
    public void putBoolean(String key, boolean value)
    public void putByteArray(String key, byte[] value)
    public void putDouble(String key, double value)
    public void putFloat(String key, float value)
    public void putInt(String key, int value)
    public void putLong(String key, long value)
    public void remove(String key)
    public void removeNode()
    public void removeNodeChangeListener(NodeChangeListener ncl)
    public void sync()
    public String   toString()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM