Well, the easiest way would be to just make your ServiceHandle function synchronized. Then only one thread could be inside at a time, and so, only a single instance of each bean would ever be created. 
That works, but could be a bottleneck, when there are lots of threads asking for those beans: they'd end up all waiting for each other at the entrance to this function. 
Here is one way to avoid that. It might look a little inolved, but what I like about it is that the most common path, after everything has been initialized does not require any synchronization or locking at all, and when a bean is being initialized, only threads, asking for that particular bean are forced to wait, while the others are unaffected:
class BeanHolder {
    // Does not need to be volatile as long as once a bean is initialized it never changes again!
    private Bean bean = null; 
    public Bean getBean(String name) {
       if(bean == null) synchronized(this) {
           if(bean == null) bean = init(name);               
       }
       return bean;
    }      
}
ConcurrentHashMap<String, BeanHolder> beans = new ConcurrentHashMap<>();
Bean serviceHandle(String name)  {
   beans.putIfAbset(name, new BeanHolder());
   return beans.get(name).getBean(name);
}