Search code examples
javamultithreadingpropertychangelistener

Change listener of variable in other thread


I have a REST Client, which is receiving an JSON object. This Client is working in an own thread and the object is updated about 10 times every second.

The main class (which created the thread) should now be able to react on changes of the specified thread object. Is a ChangeListener the most useful way? My problem is combining the Listener with the thread variable. I only know how to provide thread-safe variable-getters, but this isn't helpful now. Has anyone an example how to observe such a value from another thread?

It is not really important to handle all values. (json object contains position data) The main class should afterwards use the data to simulate a mouse move, but this isn't really relevant for the question.

Thank you guys for help!


Solution

  • ChangeListener is best and easiest way but not the only way. You can also use wait/notifyall observer pattern.You can separate the thread variable from listener using some volatile flag which you can update when you compare the new received jason string with current jason string. I have appended a dummy code that might help:

    import java.util.*;
    import java.util.concurrent.Executors;
    import java.util.concurrent.atomic.AtomicReference;
    
    public class ChangeManager{
        private Set<ChangeListener> listenerSet = new HashSet<ChangeListener>();
        private volatile boolean stateChanged;
        private Timer timer = new Timer();
        private AtomicReference<MyJasonObject> currentJasonObjectState = new AtomicReference<MyJasonObject>();
        public void start(){
            timer.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    monitorValue();
                }
    
            }, 0, 1000);
        }
        public void monitorValue(){
            // Make Rest call and check if Jason object has changed and so update the stateChanged flag.
            stateChanged = hasStateChange();
            if(stateChanged){
                Iterator<ChangeListener> i = listenerSet.iterator();
                while(i.hasNext()) {
                    i.next().notifyListener();
                }
                stateChanged = false;
            }
        }
    
        public void addListener(ChangeListener listener){
            listenerSet.add(listener);
        }
    
        public void removeListener(ChangeListener listener){
            listenerSet.remove(listener);
        }
    }
    
    interface ChangeListener {
        void notifyListener();
    }