Package org.red5.server

Source Code of org.red5.server.AtomicCounterTest$IntCountWorker

/*
* RED5 Open Source Flash Server - http://code.google.com/p/red5/
*
* Copyright 2006-2014 by respective authors (see below). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.red5.server;

import static org.junit.Assert.*;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;

import org.junit.Test;

public class AtomicCounterTest {

  private static int threads = 3;

  private static int callsPerThread = 1000;

  private static int setSize = (threads * callsPerThread);

  @Test
  public void testIntPrimative() throws Throwable {
    IntCounter i = new IntCounter();

    //pass that instance to the MTTR
    TestRunnable[] trs = new TestRunnable[threads];
    for (int t = 0; t < threads; t++) {
      trs[t] = new IntCountWorker(i);
    }

    MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);

    //kickstarts the MTTR & fires off threads
    long start = System.nanoTime();
    mttr.runTestRunnables();
    System.out.println("Runtime for int primative with synchronized: "
        + (System.nanoTime() - start) + "ns");

    //dump our ints into a set
    Set<Integer> intList = new HashSet<Integer>(setSize);
    for (TestRunnable r : trs) {
      int[] nums = ((IntCountWorker) r).getNumbers();
      for (int num : nums) {
        //a set will not allow duplicates
        intList.add(num);
      }
    }
    //check for dupes
    assertTrue(intList.size() == setSize);

  }

  @Test
  public void testAtomicInt() throws Throwable {
    AtomicIntCounter i = new AtomicIntCounter();

    //pass that instance to the MTTR
    TestRunnable[] trs = new TestRunnable[threads];
    for (int t = 0; t < threads; t++) {
      trs[t] = new AtomicIntCountWorker(i);
    }

    MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);

    //kickstarts the MTTR & fires off threads
    long start = System.nanoTime();
    mttr.runTestRunnables();
    System.out.println("Runtime for Atomic: " + (System.nanoTime() - start)
        + "ns");

    //dump our ints into a set
    Set<Integer> intList = new HashSet<Integer>(setSize);
    for (TestRunnable r : trs) {
      int[] nums = ((AtomicIntCountWorker) r).getNumbers();
      for (int num : nums) {
        //a set will not allow duplicates
        intList.add(num);
      }
    }
    //check for dupes
    assertTrue(intList.size() == setSize);

  }

  @Test
  public void testVolatileIntPrimative() throws Throwable {
    VolatileIntCounter i = new VolatileIntCounter();

    //pass that instance to the MTTR
    TestRunnable[] trs = new TestRunnable[threads];
    for (int t = 0; t < threads; t++) {
      trs[t] = new VolatileIntCountWorker(i);
    }

    MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);

    //kickstarts the MTTR & fires off threads
    long start = System.nanoTime();
    mttr.runTestRunnables();
    System.out.println("Runtime for volatile primative: "
        + (System.nanoTime() - start) + "ns");

    //dump our ints into a set
    Set<Integer> intList = new HashSet<Integer>(setSize);
    for (TestRunnable r : trs) {
      int[] nums = ((VolatileIntCountWorker) r).getNumbers();
      for (int num : nums) {
        //a set will not allow duplicates
        intList.add(num);
      }
    }
    //compare sizes.. this should be the same for volatile ints since the worker now locks
    assertEquals(intList.size(), setSize);

  }

  private class IntCountWorker extends TestRunnable {
    private IntCounter counter;

    private int[] nums = new int[callsPerThread];

    public IntCountWorker(IntCounter counter) {
      this.counter = counter;
    }

    public void runTest() throws Throwable {
      for (int i = 0; i < callsPerThread; i++) {
        nums[i] = counter.next();
      }
    }

    public int[] getNumbers() {
      return nums;
    }
  }

  private class AtomicIntCountWorker extends TestRunnable {
    private AtomicIntCounter counter;

    private int[] nums = new int[callsPerThread];

    public AtomicIntCountWorker(AtomicIntCounter counter) {
      this.counter = counter;
    }

    public void runTest() throws Throwable {
      for (int i = 0; i < callsPerThread; i++) {
        nums[i] = counter.next();
      }
    }

    public int[] getNumbers() {
      return nums;
    }
  }

  private class VolatileIntCountWorker extends TestRunnable {
    private VolatileIntCounter counter;

    private int[] nums = new int[callsPerThread];

    public VolatileIntCountWorker(VolatileIntCounter counter) {
      this.counter = counter;
    }

    public void runTest() throws Throwable {
      for (int i = 0; i < callsPerThread; i++) {
        nums[i] = counter.next();
      }
    }

    public int[] getNumbers() {
      return nums;
    }
  }

  /**
   * Simple counter using int and syncronized
   */
  public class IntCounter {

    private int counter = 0;

    public synchronized int next() {
      return counter++;
    }

    public synchronized int getCurrent() {
      return counter;
    }
  }

  /**
   * Simple counter using AtomicInteger
   */
  public class AtomicIntCounter {

    private AtomicInteger counter = new AtomicInteger();

    public int next() {
      return counter.incrementAndGet();
    }

    public int getCurrent() {
      return counter.get();
    }
  }

  /**
   * Simple counter using only a primative int and volatile
   */
  public class VolatileIntCounter {

    // Note: volatile just ensures that you're always READING the lastest
    // copy, but ++ is still not atomic, so this MUST be synced to work.
    private volatile int counter = 0;

    public int next() {
      int retval = 0;
      synchronized(this) {
        retval = counter;
        counter++;
      }
      return retval;
    }

    public int getCurrent() {
      // always an atomic read
      return counter;
    }
  }

}
TOP

Related Classes of org.red5.server.AtomicCounterTest$IntCountWorker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.