4

I have a situation where I need to give an error message when someone tries to delete an object b from a bList and it is used in some other class say class A.
If b is not referenced in another class then I should not throw an error message.

Pseudo code for the above scenario

public class A {

    B b;

    void setB(B b) {
        this.b = b;
    }
}

public class NotifyTest {

    List<B> bList = new ArrayList<>();

    String notifyTest() {

        A a = new A();
        B b = new B();
        a.setB(b);
        bList.add(b);

        if (b referencedSomewhere)   
        {
            return "error";
        }
        else
        {
             bList.remove(b);
             return  "success";
        }
    }
}

Traversing my entire model to check if object b is used somewhere is a performance hit so I don't want to go for that approach.
Please let me know if there is any solution for this scenario provided by Java or suggest a better way to handle this.

Edit1 : I need an error message when b is referenced in any other place other than bList

Prabhu
  • 27
  • 5
  • How do one "b" becomes used? –  Sep 19 '16 at 05:25
  • Assuming that b is not referenced anywhere, what's the point of bList.remove(b)? It can't exist in bList anyway if it's not referenced anywhere (including bList)? – eis Sep 19 '16 at 05:28
  • if you remove b from bList then also b is not deleted. It still remains in memory. For performing what you need to do is to assign b to null in this case. But that also does not ensure that b will be deleted – Gaur93 Sep 19 '16 at 05:29
  • 1
    See [this](http://stackoverflow.com/questions/6155464/is-it-possible-see-all-the-references-to-an-object-in-execution-time) and [this](http://stackoverflow.com/questions/5334137/is-it-possible-to-get-the-object-reference-count). – user1803551 Sep 19 '16 at 05:34
  • I need to throw an error message when b is referenced in any other place other than bList – Prabhu Sep 19 '16 at 06:02
  • @Prabhu What are the objects in the list? Can you explain a real scenario about what you're doing? – Kayaman Sep 19 '16 at 06:12

3 Answers3

1

If your intention here is to automatically free up items from the list that are no longer referenced you can use https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html

You could also use this to keep track of all keys that are not yet garbage collected. This can provide you the information about which items are already garbage collected (after becoming unreachable). However, the information won't be realtime as the garbage collector may run at arbitrary times.

Ashwinee K Jha
  • 9,187
  • 2
  • 25
  • 19
  • Thanks for the reply. My intention is to show a real time error message. I need to restrict the user from deleting an entry from the list when the entry is used in other classes except the list – Prabhu Sep 19 '16 at 06:05
1

I think something like the following should work for you. This is quickly put together to show you the idea. It has not been tested and will need more work if you want it to be thread safe.

class RefCounter<T>
{
   private HashMap<T, Integer>  counts = new HashMap<>();

   public T  using(T object)
   {
      Integer  num = counts.get(object);
      if (num == null)
         counts.put(object, 1);
      else
         counts.put(object, num+1);
      return object;
   }

   public T  release(T object)
   {
      Integer  num = counts.get(object);
      if (num == null)
         throw new IllegalArgumentException("Object not in RefCounter");
      else if (num == 1)
         counts.remove(object);
      else
         counts.put(object, num-1);
      return object;
   }


   public boolean  usedElsewhere(T object)
   {
      Integer  num = counts.get(object);
      return (num != null && num > 1);
   }

}

When you use an object, add it to RefCounter.

refCounter.using(x);
someList.add(x);

When you are done with that object

someList.remove(index);
refCounter.release(x);

To test if the object is used elsewhere

if (refCounter.usedElsewhere(x) {
   return "error";
} else {
   someList.remove(index);
   refCounter.release(x);
}

Remember you'll need to ensure you call using() and release() every time you keep or release an object, otherwise this is all pointless.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Thanks for the solution. But downside I see with this approach is I need to update a map for each add and delete. If I could not find any other solution better than this I will be implementing your idea. Once again thanks for the solution. – Prabhu Sep 19 '16 at 06:13
  • I think this is the best approach. I would include the Map into the Class B definition because is B responsability to know if it has been asigned or not. – Marco A. Hernandez Sep 19 '16 at 09:18
0

If the object is absolutely not used (or there's not much memory left) then java will mark it deleted, then when you start using up your memory, java will automatically do the garbage collection for you.

Most of the high level have garbage collection (GC), like java, C#, Python (iirc), etc. You only need to keep attention on memory if you use more low level languages, like C ir C++ (wich is somewhere between low and high level actually)

Bálint
  • 4,009
  • 2
  • 16
  • 27