I have below class structures in my project for class A and class B:
class A {
    private String id;
    private List<B> bs = new ArrayList<B>();
    A(String id){
        this.id = id;
    }
    public List<B> getBs(){
        return bs;
    }
    public void setBs(List<B> bs){
        this.bs=bs;
    }
    public void addBs(List<B> bs){
        this.bs.addAll(bs);
    }
    public void addB(B b){
        this.bs.add(b);
    }
}
class B {
    private String id;
    private List<String> tags;
    B(String id){
        this.id = id;
    }
    public List<String> getTags(){
        return tags;
    }
    public void setTags(List<String> tags){
        this.tags = tags;
    }
    public void addTags(List<String> tags){
        this.tags.addAll(tags);
    }
    public void addTag(String tag){
        this.tags.add(tag);
    }
}
Also we have a cache class:
class CacheService {
    private static final ConcurrentHashMap<String, Object> CACHE = new ConcurrentHashMap<String, Object>();
    public static Object get(String id){
        return CACHE.get(id);
    }
    public static void put(String id, Object obj){
        return CACHE.put(id, obj);
    }
}
Now objects for class A and B are created using unique IDs and put in this cache by <id, object> combination. For example:
A a1 = new A("10");
CacheService.put("10", a1);
A a2 = new A("11");
CacheService.put("11", a2);
B b1 = new B("1");
CacheService.put("1", b1);
B b2 = new B("2");
CacheService.put("2", b2);
B b3 = new B("3");
CacheService.put("3", b3);
B b4 = new B("4");
CacheService.put("4", b4);
Also I am putting class B objects in the List<B> inside objects a1 and a2. It is important to note that a unique B object is only put once in any A object:
a1.add(b1);
a1.add(b2);
a2.add(b3);
a2.add(b4);
This way we can have multiple objects for class A and B in the CACHE.
Scenario: Now multiple threads access this CACHE but some of them end up to get class A objects and others class B objects depending upon ID specified by user. These threads actually want to read or update information on these objects.
Question: My requirement is when a thread has accessed an object of class A (for example a1) to update it then no other thread should be able to read or update a1 as well as all class B objects (b1 and b2 in this case) which are added to the List<B> inside object a1 until I am finished with all updates on a1. Please tell me how can I acquire a lock in this scenario? 
 
     
     
     
    