ConcentratedClassTestApp.java :  » Net » Terracotta » com » tctest » Java Open Source

Java Open Source » Net » Terracotta 
Terracotta » com » tctest » ConcentratedClassTestApp.java
/*
 * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
 * notice. All rights reserved.
 */
package com.tctest;

import EDU.oswego.cs.dl.util.concurrent.SynchronizedRef;

import com.tc.object.config.ConfigVisitor;
import com.tc.object.config.DSOClientConfigHelper;
import com.tc.object.config.TransparencyClassSpec;
import com.tc.simulator.app.ApplicationConfig;
import com.tc.simulator.listener.ListenerProvider;
import com.tctest.runner.AbstractTransparentApp;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class ConcentratedClassTestApp extends AbstractTransparentApp {
  private static final boolean DEBUG        = false;

  private static final int     THREAD_COUNT = 5;
  private static Map           root         = new HashMap();
  final private static long    runtime      = 1000 * 200;   // 200 seconds

  public ConcentratedClassTestApp(String appId, ApplicationConfig cfg, ListenerProvider listenerProvider) {
    super(appId, cfg, listenerProvider);
    if (getParticipantCount() < 2) {
      // this test needs to have transactions coming in from other nodes (such that reflection based field set()'ing
      // occurs as DNA is applied locally
      throw new RuntimeException("Need at least 2 participants for this test");
    }
  }

  public static void visitL1DSOConfig(ConfigVisitor visitor, DSOClientConfigHelper config) {
    String testClass = ConcentratedClassTestApp.class.getName();
    TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
    String methodExpression = "* " + testClass + "*.*(..)";
    config.addWriteAutolock(methodExpression);

    spec.addRoot("root", "lock");
    config.addIncludePattern(ConcentratedClass.class.getName());
  }

  private void threadEntry(String id, int count) {

    debugPrintln("threadEntry id=[" + id + "] count=[" + count + "]");

    ConcentratedClass cc = new ConcentratedClass();

    synchronized (root) {
      final Object prev = root.put(id, cc);
      if (prev != null) { throw new RuntimeException("replaced an entry in the map for id " + id); }

      if (root.size() == count) {
        debugPrintln("notifyingAll root size matches");
        root.notifyAll();
      } else {
        while (root.size() != count) {
          try {
            debugPrintln("waiting until root size matches");
            root.wait();
          } catch (InterruptedException e) {
            throw new RuntimeException(e);
          }
        }
      }
    }

    Collection values;
    synchronized (root) {
      values = root.values();
    }

    Set all = new HashSet();

    long end = System.currentTimeMillis() + runtime;
    while (end > System.currentTimeMillis()) {
      debugPrintln("inside while loop id=[" + id + "]");

      final ConcentratedClass prevCC;
      final ConcentratedClass newCC = new ConcentratedClass();
      all.add(newCC);

      synchronized (root) {
        prevCC = (ConcentratedClass) root.put(id, newCC);
        values = root.values();
      }

      try {
        Thread.sleep((int) (Math.random() * 10));
      } catch (Exception e) {
        //
      }

      if (values.size() != count) { throw new RuntimeException("unexpected size: " + values.size()); }

      all.add(prevCC);
      for (Iterator iter = all.iterator(); iter.hasNext();) {
        ConcentratedClass someCC = (ConcentratedClass) iter.next();
        someCC.increment();
      }
    }

    debugPrintln("while loop ends id=[" + id + "]");
  }

  public void run() {
    final SynchronizedRef error = new SynchronizedRef(null);
    final String id = getApplicationId();

    debugPrintln("Starting app run id=[" + id + "] threadCount=[" + THREAD_COUNT + "]");

    Thread threads[] = new Thread[THREAD_COUNT];
    for (int i = 0; i < threads.length; i++) {
      final int cnt = i;
      threads[i] = new Thread(new Runnable() {
        public void run() {
          try {
            threadEntry(id + cnt, getParticipantCount() * THREAD_COUNT);
          } catch (Throwable t) {
            error.set(t);
          }
        }
      });
    }

    for (int i = 0; i < threads.length; i++) {
      threads[i].start();
    }

    for (int i = 0; i < threads.length; i++) {
      try {
        threads[i].join(runtime + 1000);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }

    Throwable t = (Throwable) error.get();
    if (t != null) { throw new RuntimeException(t); }
  }

  private static class ConcentratedClass {
    // Leave these fields private! This test is trying to shake out concurrency problems set/get()'ing private
    // fields via reflection in GenericTCField
    private int counter1 = 0;
    private int counter2 = 0;

    synchronized int increment() {
      counter1++;
      counter2++;
      return counter1;
    }
  }

  private void debugPrintln(String s) {
    if (DEBUG) {
      System.err.println("***** ConcentratedClassTestApp: " + s);
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.