### Question:
Groups { public synchronized Group getOrCreate( String name ) { if ( isGlobalGroup( name ) ) { return Group.GLOBAL; } Group group = byName.get( name ); if ( group == null ) { byName.put( name, group = new Group.Adapter( nextId++, name ) ); byId.add( group ); } return group; }  synchronized Group getOrCreate( String name ); synchronized Group get( String name ); Group get( int id ); int size();  }### Answer:
@Test public void shouldHandleConcurrentGetOrCreate() throws Throwable { Groups groups = new Groups(); Race race = new Race(); String name = "MyGroup"; for ( int i = 0; i < Runtime.getRuntime().availableProcessors(); i++ ) { race.addContestant( () -> { Group group = groups.getOrCreate( name ); assertEquals( LOWEST_NONGLOBAL_ID, group.id() ); } ); } race.go(); Group otherGroup = groups.getOrCreate( "MyOtherGroup" ); assertEquals( LOWEST_NONGLOBAL_ID + 1, otherGroup.id() ); }
@Test public void shouldSupportMixedGroupModeInGetOrCreate() { Groups groups = new Groups(); assertEquals( Group.GLOBAL, groups.getOrCreate( null ) ); assertNotEquals( Group.GLOBAL, groups.getOrCreate( "Something" ) ); }
@Test public void shouldSupportMixedGroupModeInGetOrCreate2() { Groups groups = new Groups(); assertNotEquals( Group.GLOBAL, groups.getOrCreate( "Something" ) ); assertEquals( Group.GLOBAL, groups.getOrCreate( null ) ); }