Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Java
  4. Using the Observer and Observable Class

Using the Observer and Observable Class

Scheduled Pinned Locked Moved Java
javadata-structurestestingbeta-testingperformance
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Ryan Little
    wrote on last edited by
    #1

    I am writing a small data driven application which takes data from an input and throw an event throughout the program that is subscribed to the data event listener. Currently, I have the small test program setup as an infinite loop to see if there are any memory leaks. Testing has shown that there is a massive memory leak and I don't know what to do. I have the program attached: What is happening is when the event is handled, it is not properly disposed of. Instead, it is thrown onto the stack while a new event is serviced. I thought sleeping the current event would dispose of the last event but...nope! I am out of ideas on how to properly service and dispose of events quickly using this form. Any ideas would be helpful to figure this small technical issue out. Thanks - Ryan The Main loop which has the data items and the main value observer.

    import java.util.*;

    public class CMain {

    private final static int TIMEOUT = 250;
    
    // Public data...Could be in the form of a singleton.
    private static CValue Value;
    
    private static CData AddFive;
    private static CData AddTwo;
    private static CData AddTen;
    private static CData AddSeven;
    private static CData MaxValueReached;
    
    public static void main(String\[\] args) {
    	// All the data variables which will be used
    	Value = new CValue();
    	
    	AddFive = new CData();
    	AddFive.setItsAction(new CAction()
    	{
    
    		@Override
    		public void doAction() throws InterruptedException {
    			Thread.sleep(TIMEOUT);
    			if (Value.getItsValue() <= 20)
    			{
    				Value.setItsValue(Value.getItsValue() + 5);
    			}
    		}
    		
    	});
    	Value.addObserver(AddFive);
    	
    	AddTwo = new CData();
    	AddTwo.setItsAction(new CAction()
    	{
    		public void doAction() throws InterruptedException{
    			Thread.sleep(TIMEOUT);
    			if (Value.getItsValue() > 20 && Value.getItsValue() <= 40)
    			{
    				Value.setItsValue(Value.getItsValue() + 2);
    			}
    		}
    	});
    	Value.addObserver(AddTwo);
    	
    	AddTen = new CData();
    	AddTen.setItsAction(new CAction(){
    		public void doAction() throws InterruptedException{
    			Thread.sleep(TIMEOUT);
    			if (Value.getItsValue() > 40 && Value.getItsValue() <= 80)
    			{
    				Value.setItsValue(Value.getItsValue() + 10);
    			}
    		}
    	});
    	Value.addObserver(AddTen);
    	
    	AddSeven = new CData();
    	AddSeven.setItsAction(new CAction(){
    		public void doAction() throws InterruptedException{
    			Thread.sleep(TIMEOUT);
    			if (Value.getItsValue() > 80)
    			{
    				Value.setItsValue(Value.getItsValue(
    
    S 1 Reply Last reply
    0
    • R Ryan Little

      I am writing a small data driven application which takes data from an input and throw an event throughout the program that is subscribed to the data event listener. Currently, I have the small test program setup as an infinite loop to see if there are any memory leaks. Testing has shown that there is a massive memory leak and I don't know what to do. I have the program attached: What is happening is when the event is handled, it is not properly disposed of. Instead, it is thrown onto the stack while a new event is serviced. I thought sleeping the current event would dispose of the last event but...nope! I am out of ideas on how to properly service and dispose of events quickly using this form. Any ideas would be helpful to figure this small technical issue out. Thanks - Ryan The Main loop which has the data items and the main value observer.

      import java.util.*;

      public class CMain {

      private final static int TIMEOUT = 250;
      
      // Public data...Could be in the form of a singleton.
      private static CValue Value;
      
      private static CData AddFive;
      private static CData AddTwo;
      private static CData AddTen;
      private static CData AddSeven;
      private static CData MaxValueReached;
      
      public static void main(String\[\] args) {
      	// All the data variables which will be used
      	Value = new CValue();
      	
      	AddFive = new CData();
      	AddFive.setItsAction(new CAction()
      	{
      
      		@Override
      		public void doAction() throws InterruptedException {
      			Thread.sleep(TIMEOUT);
      			if (Value.getItsValue() <= 20)
      			{
      				Value.setItsValue(Value.getItsValue() + 5);
      			}
      		}
      		
      	});
      	Value.addObserver(AddFive);
      	
      	AddTwo = new CData();
      	AddTwo.setItsAction(new CAction()
      	{
      		public void doAction() throws InterruptedException{
      			Thread.sleep(TIMEOUT);
      			if (Value.getItsValue() > 20 && Value.getItsValue() <= 40)
      			{
      				Value.setItsValue(Value.getItsValue() + 2);
      			}
      		}
      	});
      	Value.addObserver(AddTwo);
      	
      	AddTen = new CData();
      	AddTen.setItsAction(new CAction(){
      		public void doAction() throws InterruptedException{
      			Thread.sleep(TIMEOUT);
      			if (Value.getItsValue() > 40 && Value.getItsValue() <= 80)
      			{
      				Value.setItsValue(Value.getItsValue() + 10);
      			}
      		}
      	});
      	Value.addObserver(AddTen);
      	
      	AddSeven = new CData();
      	AddSeven.setItsAction(new CAction(){
      		public void doAction() throws InterruptedException{
      			Thread.sleep(TIMEOUT);
      			if (Value.getItsValue() > 80)
      			{
      				Value.setItsValue(Value.getItsValue(
      
      S Offline
      S Offline
      Shubhashish_Mandal
      wrote on last edited by
      #2

      I think you failed to understand the publisher-subscriber framework. Publisher has many subscriber .i.e one to many relation ship with subscriber.Publisher post the new event(if any), and all the subscriber which have the subscription, will catch the event. So this is pretty much concept. In java , publisher as Observable and subscriber as Observer. Now, in your app you create an Observable (CValue). Then you create Observer which is again an Observable(CData extends Observable) and register this with the Observable, means you register an Observable with another Observable. So fixed this things before moving forward

      Regards Shubhashish

      R 1 Reply Last reply
      0
      • S Shubhashish_Mandal

        I think you failed to understand the publisher-subscriber framework. Publisher has many subscriber .i.e one to many relation ship with subscriber.Publisher post the new event(if any), and all the subscriber which have the subscription, will catch the event. So this is pretty much concept. In java , publisher as Observable and subscriber as Observer. Now, in your app you create an Observable (CValue). Then you create Observer which is again an Observable(CData extends Observable) and register this with the Observable, means you register an Observable with another Observable. So fixed this things before moving forward

        Regards Shubhashish

        R Offline
        R Offline
        Ryan Little
        wrote on last edited by
        #3

        Shubhashish, thank you for taking the time to analyze and reply to my original message. I am learning new concepts in Java to become a better programmer. I have taken you comments into serious consideration and updated the code. The class headers for CValue and CData are as follows:

        public class CValue extends Observable
        public class CData implements Observer

        I would execute the test program for a minute to two minutes before its crashes out. What I am observing during execution is this: CMain.doAction() CValue.setItsValue(double) CValue.notifyObservers() CData.update(Observerable,Object) CMain.doAction ... Repeat until thread crash It seems the events are not being closed completely after the servicing of the observer. I know I am creating a lot of events being generated quickly but isn't there a mechanism which would close these events or am I not closing them down properly myself? Ryan

        S 1 Reply Last reply
        0
        • R Ryan Little

          Shubhashish, thank you for taking the time to analyze and reply to my original message. I am learning new concepts in Java to become a better programmer. I have taken you comments into serious consideration and updated the code. The class headers for CValue and CData are as follows:

          public class CValue extends Observable
          public class CData implements Observer

          I would execute the test program for a minute to two minutes before its crashes out. What I am observing during execution is this: CMain.doAction() CValue.setItsValue(double) CValue.notifyObservers() CData.update(Observerable,Object) CMain.doAction ... Repeat until thread crash It seems the events are not being closed completely after the servicing of the observer. I know I am creating a lot of events being generated quickly but isn't there a mechanism which would close these events or am I not closing them down properly myself? Ryan

          S Offline
          S Offline
          Shubhashish_Mandal
          wrote on last edited by
          #4

          Please update the code with your changes. May be there are some memory leak. This may help you http://www.java2s.com/Code/Java/Design-Pattern/AsimpledemoofObservableandObserver.htm[^]

          Regards Shubhashish

          R 1 Reply Last reply
          0
          • S Shubhashish_Mandal

            Please update the code with your changes. May be there are some memory leak. This may help you http://www.java2s.com/Code/Java/Design-Pattern/AsimpledemoofObservableandObserver.htm[^]

            Regards Shubhashish

            R Offline
            R Offline
            Ryan Little
            wrote on last edited by
            #5

            I have been using java2s for all my questions on this problem. Updated Code: (Use the original posted code for classes not posted here)

            public class CData implements Observer
            {
            public CData()
            {
            // Do Nothing
            }
            @Override
            public void update(Observable arg0, Object arg1) {
            if (itsAction != null)
            {
            try {
            this.itsAction.doAction();
            } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
            }
            }

            private CAction itsAction = null;
            
            public CAction getItsAction() {
            	return itsAction;
            }
            public void setItsAction(CAction itsAction) {
            	this.itsAction = itsAction;
            }
            

            }

            public class CValue extends Observable
            {
            private double itsValue = 0;

            	public double getItsValue() {
            		return itsValue;
            	}
            
            	public void setItsValue(double itsValue) {
            		if (this.itsValue != itsValue)
            		{
            			this.itsValue = itsValue;
            			System.out.print("Value set to " + itsValue + "\\n");
            			setChanged();
            			notifyObservers();
            		}
            	}
            	
            	public void startBehavior()
            	{
            		setChanged();
            		notifyObservers();
            	}
            }
            

            Observation: When I execute setChanged and then execute notifyObservers, the test program does a re-calculation on the new data. If the re-calculation doesn't change the value, then no new notifications are required. If there is a change in data from the re-calculation then the process is started all over again. I made a small modification to CMain to stop the notifications after a period of time and restart the re-calculation process again. This is eliminating the memory leak completely. From these new revelations, attached is my new CMain code

            public class CMain {

            private final static int TIMEOUT = 5;
            
            // Public data...Could be in the form of a singleton.
            private static CValue Value;
            
            private static CData AddFive;
            private static CData AddTwo;
            private static CData AddTen;
            private static CData AddSeven;
            private static CData MaxValueReached;
            
            public static void main(String\[\] args) {
            	// All the data variables which will be used
            	Value = new CValue();
            	
            	AddFive = new CData();
            	AddFive.setItsAction(new CAction()
            	{
            
            		@Override
            		public void doAction() throws InterruptedException {
            			Thread.sleep(TIMEOUT);
            			if (Value.getItsValue() <= 20)
            			{
            				Value.setItsValue(Value.getItsValue() + 5);
            			}
            		}
            		
            	});
            	Value.addObserver(AddFive);
            	
            	AddTwo = new CData();
            	AddTwo.setItsAction(new CActi
            
            S 1 Reply Last reply
            0
            • R Ryan Little

              I have been using java2s for all my questions on this problem. Updated Code: (Use the original posted code for classes not posted here)

              public class CData implements Observer
              {
              public CData()
              {
              // Do Nothing
              }
              @Override
              public void update(Observable arg0, Object arg1) {
              if (itsAction != null)
              {
              try {
              this.itsAction.doAction();
              } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
              }
              }
              }

              private CAction itsAction = null;
              
              public CAction getItsAction() {
              	return itsAction;
              }
              public void setItsAction(CAction itsAction) {
              	this.itsAction = itsAction;
              }
              

              }

              public class CValue extends Observable
              {
              private double itsValue = 0;

              	public double getItsValue() {
              		return itsValue;
              	}
              
              	public void setItsValue(double itsValue) {
              		if (this.itsValue != itsValue)
              		{
              			this.itsValue = itsValue;
              			System.out.print("Value set to " + itsValue + "\\n");
              			setChanged();
              			notifyObservers();
              		}
              	}
              	
              	public void startBehavior()
              	{
              		setChanged();
              		notifyObservers();
              	}
              }
              

              Observation: When I execute setChanged and then execute notifyObservers, the test program does a re-calculation on the new data. If the re-calculation doesn't change the value, then no new notifications are required. If there is a change in data from the re-calculation then the process is started all over again. I made a small modification to CMain to stop the notifications after a period of time and restart the re-calculation process again. This is eliminating the memory leak completely. From these new revelations, attached is my new CMain code

              public class CMain {

              private final static int TIMEOUT = 5;
              
              // Public data...Could be in the form of a singleton.
              private static CValue Value;
              
              private static CData AddFive;
              private static CData AddTwo;
              private static CData AddTen;
              private static CData AddSeven;
              private static CData MaxValueReached;
              
              public static void main(String\[\] args) {
              	// All the data variables which will be used
              	Value = new CValue();
              	
              	AddFive = new CData();
              	AddFive.setItsAction(new CAction()
              	{
              
              		@Override
              		public void doAction() throws InterruptedException {
              			Thread.sleep(TIMEOUT);
              			if (Value.getItsValue() <= 20)
              			{
              				Value.setItsValue(Value.getItsValue() + 5);
              			}
              		}
              		
              	});
              	Value.addObserver(AddFive);
              	
              	AddTwo = new CData();
              	AddTwo.setItsAction(new CActi
              
              S Offline
              S Offline
              Shubhashish_Mandal
              wrote on last edited by
              #6

              few things that you have to know. Role of the Observer is to notify each subscriber if any changes happen. If you see in your code there is a recursive call exist. In your main class , at the end, you are setting value in Observer. So Observer value changed and it convey the notify message to the subscriber.Again If you see in doAction() ,you can see that each Subscriber receive the notify message and again set the Observer value with new one. There for this action again update the Observer value and again Observer doing the above thing and thus fall in recursive call.

              Regards Shubhashish

              A 1 Reply Last reply
              0
              • S Shubhashish_Mandal

                few things that you have to know. Role of the Observer is to notify each subscriber if any changes happen. If you see in your code there is a recursive call exist. In your main class , at the end, you are setting value in Observer. So Observer value changed and it convey the notify message to the subscriber.Again If you see in doAction() ,you can see that each Subscriber receive the notify message and again set the Observer value with new one. There for this action again update the Observer value and again Observer doing the above thing and thus fall in recursive call.

                Regards Shubhashish

                A Offline
                A Offline
                angrybobcat
                wrote on last edited by
                #7

                Where "Observer" is actually "Observable" as you got it right in your first post, since "Observer" and "Subscriber" are basically the same thing.

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups