--- /dev/null
+
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ int timeToSleep;
+ if (args.length > 0) {
+ timeToSleep = Integer.parseInt(args[0]);
+ } else {
+ timeToSleep = 0;
+ }
+
+ Model dataModel = new Model();
+
+ @SuppressWarnings("unused")
+ View view1 = new View(dataModel);
+ View view2 = new View(dataModel);
+ dataModel.setDataAsynchronously();
+ Thread.sleep(timeToSleep);
+
+ // For some (here unspecified) reason, we want to freeze view2
+ // so that it doesn't receive any notifications about changed
+ // data.
+ view2.freeze();
+ System.out.println("sfg");
+ // Now we want notifications about updates again.
+ view2.thaw();
+
+
+ System.out.println("Main thread finished");
+ }
+}
--- /dev/null
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is an example of a data model that implements the
+ * Observer pattern and also tries to be thread-safe. Updates to the
+ * model are considered taking a long time and are therefore performed
+ * in a background thread.
+ */
+public class Model {
+ public interface Listener {
+ /** Called when the model has been updated. */
+ void modelUpdated();
+ }
+
+ /** A list of listeners. */
+ private List<Listener> mListeners = new ArrayList<Listener>();
+
+ // Some mutable data fields here...
+
+ /**
+ * Register a new listener to changes of data in the model.
+ *
+ * @param listener Listener to subscribe.
+ */
+ synchronized public void registerListener(Listener listener) {
+ mListeners.add(listener);
+ }
+
+ /**
+ * Unregister a listener.
+ *
+ * @param listener Listener to unsubscribe.
+ */
+ synchronized public void unregisterListener(Listener listener) {
+ mListeners.remove(listener);
+ }
+
+ /**
+ * Modify the model's data.
+ *
+ * Since the update can take a long time, it is performed in a
+ * background thread. When the update has been completed, the
+ * listeners are notified.
+ */
+ public void setDataAsynchronously() {
+ Thread updateThread = new Thread("modelUpdateThread") {
+ public void run() {
+ System.out.println("Updating the model");
+ // Set data fields here...
+ notifyListeners();
+ };
+ };
+ updateThread.start();
+ }
+
+ /**
+ * Notify listeners that the data has been modified.
+ */
+ synchronized private void notifyListeners() {
+ System.out.println("Notifying listeners");
+ for (Listener listener : mListeners) {
+ listener.modelUpdated();
+ }
+ }
+}
--- /dev/null
+
+
+public class View implements Model.Listener {
+ private Model mDataModel;
+ private boolean mFrozen = false;
+
+ public View(Model dataModel) {
+ mDataModel = dataModel;
+ System.out.println("Registering view in data model");
+ dataModel.registerListener(this);
+ }
+
+ synchronized void freeze() {
+ if (!mFrozen) {
+ System.out.println("Freezing view");
+ mDataModel.unregisterListener(this);
+ System.out.println("Freezing view2");
+ mFrozen = true;
+ }
+ }
+
+ synchronized void thaw() {
+ if (mFrozen) {
+ System.out.println("Thawing view");
+ mDataModel.registerListener(this);
+ mFrozen = false;
+ }
+ }
+
+ synchronized public void modelUpdated() {
+ // ...
+ }
+}