Search code examples
javamultithreadingsynchronizationwait

Java synchronization using .wait(millis)


I have a "little problem" about synchronization, this is my Scenario (I still don't know enough about synchronization, I'm still learning): (EDIT)

        Thread work, progress;
        final Object myObject;
        work = new Thread(() -> {
            try {
                myObject.doSomething();
            } catch (IOException e) {e.printStackTrace();}
        });

        progress = new Thread(() -> {
            while (true) {
                System.out.println(myObject.progress());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        });

        work.setDaemon(true);
        progress.setDaemon(true);

        work.start();
        progress.start();

        work.join();
        progress.interrupt();
        progress.join();

        /*Other code*/

(EDIT: maybe solved)

The main job is done in the WORK thread, and the progress of the job is printed in the PROGRESS thread;

This works good, but I'd like a better... "synchronization": The only 'little' problem is that, if I put like 1 hour in the sleep method, maybe the job is already done and must wait those 55 minutes for the PROGRESS thread to terminate... How to deal with this situation? I want my PROGRESS thread to terminate as the job is done, and not waiting for the sleep method to complete. I suppose I'll have to use some synchronized blocks, as well as a .wait(millis) call instead of that .sleep(millis)... Can someone help me undestand? Thanks!


Solution

  • Perhaps you may want to look into the Observer/Listener pattern. To put it simply, your Observer will do nothing until it gets notified by the class it's subscribed to.

    http://www.javaworld.com/article/2077258/learn-java/observer-and-observable.html

    // Your observable class
    import java.util.Observable;
    public class ObservableValue extends Observable
    {
        private int n = 0;
        public ObservableValue(int n)
        {
            this.n = n;
        }
        public void setValue(int n)
        {
            this.n = n;
            setChanged();
            notifyObservers();
        }
        public int getValue()
        {
            return n;
        }
    }
    
    
    // Your observer
    import java.util.Observer;
    import java.util.Observable;
    public class TextObserver implements Observer {
        private ObservableValue ov = null;
        public TextObserver(ObservableValue ov) {
            this.ov = ov;
        }
        public void update(Observable obs, Object obj) {
            if (obs == ov) {
                System.out.println(ov.getValue());
            }
        }
    }
    
    
    public class Main {
        public Main() {
            ObservableValue ov = new ObservableValue(0);
            TextObserver to = new TextObserver(ov);
            ov.addObserver(to);
        }
        public static void main(String [] args) {
            Main m = new Main();
        }
    }
    

    An example of using the observer pattern with multithreading can be found here: https://dzone.com/articles/the-observer-pattern-using-modern-java

    An interesting approach to this problem is using Reactive principles. A quick demonstration and explanation can be seen in this video: https://www.youtube.com/watch?v=weWSYIUdX6c