fork(2) download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6.  
  7. class Collection1<T> {
  8.  
  9. private volatile transient int count = 0;
  10.  
  11. protected synchronized int getCount() {
  12. return count;
  13. }
  14.  
  15. public void add(T t) {
  16. count++;
  17. }
  18.  
  19. public void addRange(T[] ts) {
  20. for (T t : ts) { add(t); };
  21. // count = count + ts.length;
  22. }
  23. }
  24.  
  25. class Collection2<T> extends Collection1<T> {
  26.  
  27. protected class AddCounter {
  28. int[] addCount = new int[]{-10,-10,-10,-10,-10,-10,-10,-10,-10,-10};
  29. int addLevel = -1;
  30. int checkLevel = 0;
  31.  
  32. protected void beginAdd() {
  33. addLevel++;
  34. if (addLevel == checkLevel) {
  35. addCount[checkLevel] = 0;
  36. }
  37. }
  38.  
  39. protected void endAdd() {
  40. if ((addLevel == checkLevel) && (checkLevel > 0)) {
  41. addCount[checkLevel - 1] = addCount[checkLevel - 1] + addCount[checkLevel];
  42. }
  43. addLevel--;
  44. }
  45.  
  46. protected void completeAdd(int count) {
  47. if (addLevel == checkLevel) {
  48. addCount[checkLevel] = addCount[checkLevel] + count;
  49. }
  50. }
  51. }
  52.  
  53. protected ThreadLocal<AddCounter> addCounter = new ThreadLocal<AddCounter>() {
  54. @Override
  55. protected AddCounter initialValue() {
  56. return new AddCounter();
  57. }
  58. };
  59.  
  60. public int getAddCount() {
  61. AddCounter ac = addCounter.get();
  62. return ac.addCount[ac.checkLevel];
  63. }
  64.  
  65. public void beginAdd() {
  66. AddCounter ac = addCounter.get();
  67. ac.beginAdd();
  68. ac.checkLevel++;
  69. }
  70.  
  71. public void endAdd() {
  72. AddCounter ac = addCounter.get();
  73. ac.checkLevel--;
  74. ac.endAdd();
  75. }
  76.  
  77. @Override
  78. public void add(T t) {
  79. AddCounter ac = addCounter.get();
  80. ac.beginAdd();
  81. try {
  82. super.add(t);
  83. ac.completeAdd(1);
  84. } finally {
  85. ac.endAdd();
  86. }
  87. }
  88.  
  89. @Override
  90. public void addRange(T[] ts) {
  91. AddCounter ac = addCounter.get();
  92. ac.beginAdd();
  93. try {
  94. super.addRange(ts);
  95. ac.completeAdd(ts.length);
  96. } finally {
  97. ac.endAdd();
  98. }
  99. }
  100. }
  101.  
  102. /* Name of the class has to be "Main" only if the class is public. */
  103. class Ideone
  104. {
  105. public static boolean sleep2(int value) {
  106. try {
  107. Thread.sleep(value);
  108. return false;
  109. } catch (InterruptedException e) {
  110. return true;
  111. }
  112. }
  113.  
  114. public static void main (String[] args) throws java.lang.Exception
  115. {
  116. Collection2<Object> cc;
  117.  
  118. cc = new Collection2<>();
  119.  
  120. Thread t1 = new Thread(new Runnable() {
  121. @Override
  122. public void run() {
  123. cc.add(null);
  124. if (sleep2(10)) { return; }
  125. System.out.println("tr1: Count = " + cc.getCount() + ", add count = " + cc.getAddCount());
  126. }
  127. });
  128.  
  129.  
  130. Thread t2 = new Thread(new Runnable() {
  131. @Override
  132. public void run() {
  133. if (sleep2(10)) { return; }
  134. cc.addRange(new Object[3]);
  135. if (sleep2(10)) { return; }
  136. System.out.println("tr2: Count = " + cc.getCount() + ", add count = " + cc.getAddCount());
  137. }
  138. });
  139.  
  140. Thread t3 = new Thread(new Runnable() {
  141. @Override
  142. public void run() {
  143. cc.beginAdd();
  144. try {
  145. cc.beginAdd();
  146. try {
  147. if (sleep2(10)) { return; }
  148. cc.add(null);
  149. if (sleep2(10)) { return; }
  150. cc.add(null);
  151. } finally {
  152. cc.endAdd();
  153. }
  154. System.out.println("tr3 2: Count = " + cc.getCount() + ", add count = " + cc.getAddCount());
  155. if (sleep2(10)) { return; }
  156. cc.addRange(new Object[5]);
  157. } finally {
  158. cc.endAdd();
  159. }
  160.  
  161. System.out.println("tr3 1: Count = " + cc.getCount() + ", add count = " + cc.getAddCount());
  162. }
  163. });
  164.  
  165. t3.start();
  166. t2.start();
  167. t1.start();
  168.  
  169. }
  170. }
Success #stdin #stdout 0.04s 711168KB
stdin
Standard input is empty
stdout
tr1: Count = 5, add count = 1
tr3 2: Count = 6, add count = 2
tr2: Count = 6, add count = 3
tr3 1: Count = 11, add count = 7