- /* package whatever; // don't place package name! */ 
-   
- import java.util.*; 
- import java.lang.*; 
- import java.io.*; 
-   
- class Collection1<T>  { 
-   
- 	private volatile transient int count = 0; 
-   
-     protected synchronized int getCount() { 
-     	return count; 
-     } 
-   
- 	public void add(T t) { 
- 		count++; 
- 	} 
-   
- 	public void addRange(T[] ts) { 
- 		for (T t : ts) {  add(t); }; 
- //		count = count + ts.length; 
- 	} 
- } 
-   
- class Collection2<T>  extends Collection1<T> { 
-   
- 	protected class AddCounter { 
- 		int[] addCount = new int[]{-10,-10,-10,-10,-10,-10,-10,-10,-10,-10}; 
- 		int addLevel = -1; 
- 		int checkLevel = 0; 
-   
- 		protected void beginAdd() { 
- 			addLevel++; 
- 			if (addLevel == checkLevel) { 
- 				addCount[checkLevel] = 0; 
- 			} 
- 		}	 
-   
- 		protected void endAdd() { 
- 			if ((addLevel == checkLevel) && (checkLevel > 0)) { 
- 				addCount[checkLevel - 1] = addCount[checkLevel - 1] + addCount[checkLevel]; 
- 			} 
- 			addLevel--; 
- 		}			 
-   
- 		protected void completeAdd(int count) { 
- 			if (addLevel == checkLevel) { 
- 				addCount[checkLevel] = addCount[checkLevel] + count; 
- 			} 
- 		}	 
- 	}	 
-   
- 	protected ThreadLocal<AddCounter> addCounter = new ThreadLocal<AddCounter>() { 
-             @Override 
-             protected AddCounter initialValue() { 
-                 return new AddCounter(); 
-             }           
-         }; 
-   
- 	public int getAddCount() { 
- 		AddCounter ac = addCounter.get(); 
- 	   	return ac.addCount[ac.checkLevel];	 
- 	} 
-   
- 	public void beginAdd() { 
- 		AddCounter ac = addCounter.get(); 
- 		ac.beginAdd(); 
-      	ac.checkLevel++; 
- 	}	 
-   
- 	public void endAdd() { 
- 		AddCounter ac = addCounter.get(); 
- 		ac.checkLevel--; 
- 		ac.endAdd(); 
- 	} 
-   
- 	@Override 
- 	public void add(T t) { 
- 		AddCounter ac = addCounter.get(); 
- 		ac.beginAdd(); 
- 		try { 
- 			super.add(t); 
- 			ac.completeAdd(1); 
- 		} finally { 
- 			ac.endAdd();	 
- 		} 
- 	} 
-   
- 	@Override 
- 	public void addRange(T[] ts) { 
- 		AddCounter ac = addCounter.get(); 
- 		ac.beginAdd(); 
- 		try { 
- 			super.addRange(ts); 
- 			ac.completeAdd(ts.length); 
- 		} finally { 
- 			ac.endAdd();	 
- 		} 
- 	} 
- } 
-   
- /* Name of the class has to be "Main" only if the class is public. */ 
- class Ideone 
- { 
- 	public static boolean sleep2(int value) { 
- 		try { 
- 			return false; 
- 			return true; 
- 		} 
- 	} 
-   
- 	{ 
- 		Collection2<Object> cc; 
-   
- 		cc = new Collection2<>(); 
-   
-  	 		@Override 
-     		public void run() { 
- 				cc.add(null); 
- 				if (sleep2(10)) { return; } 
- 				System- . out- . println("tr1: Count = " +-  cc. getCount() + ", add count = " +-  cc. getAddCount());
 
-     		} 
-  	 	}); 
-   
-   
-  	 		@Override 
-     		public void run() { 
- 				if (sleep2(10)) { return; } 
- 				if (sleep2(10)) { return; } 
- 				System- . out- . println("tr2: Count = " +-  cc. getCount() + ", add count = " +-  cc. getAddCount());
 
-     		} 
-  	 	}); 
-   
-  	 		@Override 
-     		public void run() { 
- 				cc.beginAdd(); 
- 				try { 
- 					cc.beginAdd();				 
- 					try { 
- 						if (sleep2(10)) { return; } 
- 						cc.add(null); 
- 						if (sleep2(10)) { return; } 
- 						cc.add(null); 
- 					} finally {	 
- 						cc.endAdd(); 
- 					} 
- 						System- . out- . println("tr3 2: Count = " +-  cc. getCount() + ", add count = " +-  cc. getAddCount());
 
- 					if (sleep2(10)) { return; } 
- 				} finally { 
- 					cc.endAdd(); 
- 				} 
-   
- 				System- . out- . println("tr3 1: Count = " +-  cc. getCount() + ", add count = " +-  cc. getAddCount());
 
-     		} 
-  	 	}); 
-   
-  	 	t3.start(); 
-  	 	t2.start(); 
-  	 	t1.start(); 
-   
- 	} 
- }