001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math3.stat.descriptive;
018
019import org.apache.commons.math3.exception.MathIllegalArgumentException;
020import org.apache.commons.math3.exception.NullArgumentException;
021import org.apache.commons.math3.util.MathUtils;
022
023/**
024 * Implementation of
025 * {@link org.apache.commons.math3.stat.descriptive.DescriptiveStatistics} that
026 * is safe to use in a multithreaded environment.  Multiple threads can safely
027 * operate on a single instance without causing runtime exceptions due to race
028 * conditions.  In effect, this implementation makes modification and access
029 * methods atomic operations for a single instance.  That is to say, as one
030 * thread is computing a statistic from the instance, no other thread can modify
031 * the instance nor compute another statistic.
032 *
033 * @since 1.2
034 * @version $Id: SynchronizedDescriptiveStatistics.java 1416643 2012-12-03 19:37:14Z tn $
035 */
036public class SynchronizedDescriptiveStatistics extends DescriptiveStatistics {
037
038    /** Serialization UID */
039    private static final long serialVersionUID = 1L;
040
041    /**
042     * Construct an instance with infinite window
043     */
044    public SynchronizedDescriptiveStatistics() {
045        // no try-catch or advertized IAE because arg is valid
046        this(INFINITE_WINDOW);
047    }
048
049    /**
050     * Construct an instance with finite window
051     * @param window the finite window size.
052     * @throws MathIllegalArgumentException if window size is less than 1 but
053     * not equal to {@link #INFINITE_WINDOW}
054     */
055    public SynchronizedDescriptiveStatistics(int window) throws MathIllegalArgumentException {
056        super(window);
057    }
058
059    /**
060     * A copy constructor. Creates a deep-copy of the {@code original}.
061     *
062     * @param original the {@code SynchronizedDescriptiveStatistics} instance to copy
063     * @throws NullArgumentException if original is null
064     */
065    public SynchronizedDescriptiveStatistics(SynchronizedDescriptiveStatistics original)
066    throws NullArgumentException {
067        copy(original, this);
068    }
069
070    /**
071     * {@inheritDoc}
072     */
073    @Override
074    public synchronized void addValue(double v) {
075        super.addValue(v);
076    }
077
078    /**
079     * {@inheritDoc}
080     */
081    @Override
082    public synchronized double apply(UnivariateStatistic stat) {
083        return super.apply(stat);
084    }
085
086    /**
087     * {@inheritDoc}
088     */
089    @Override
090    public synchronized void clear() {
091        super.clear();
092    }
093
094    /**
095     * {@inheritDoc}
096     */
097    @Override
098    public synchronized double getElement(int index) {
099        return super.getElement(index);
100    }
101
102    /**
103     * {@inheritDoc}
104     */
105    @Override
106    public synchronized long getN() {
107        return super.getN();
108    }
109
110    /**
111     * {@inheritDoc}
112     */
113    @Override
114    public synchronized double getStandardDeviation() {
115        return super.getStandardDeviation();
116    }
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public synchronized double[] getValues() {
123        return super.getValues();
124    }
125
126    /**
127     * {@inheritDoc}
128     */
129    @Override
130    public synchronized int getWindowSize() {
131        return super.getWindowSize();
132    }
133
134    /**
135     * {@inheritDoc}
136     */
137    @Override
138    public synchronized void setWindowSize(int windowSize) throws MathIllegalArgumentException {
139        super.setWindowSize(windowSize);
140    }
141
142    /**
143     * {@inheritDoc}
144     */
145    @Override
146    public synchronized String toString() {
147        return super.toString();
148    }
149
150    /**
151     * Returns a copy of this SynchronizedDescriptiveStatistics instance with the
152     * same internal state.
153     *
154     * @return a copy of this
155     */
156    @Override
157    public synchronized SynchronizedDescriptiveStatistics copy() {
158        SynchronizedDescriptiveStatistics result =
159            new SynchronizedDescriptiveStatistics();
160        // No try-catch or advertised exception because arguments are guaranteed non-null
161        copy(this, result);
162        return result;
163    }
164
165    /**
166     * Copies source to dest.
167     * <p>Neither source nor dest can be null.</p>
168     * <p>Acquires synchronization lock on source, then dest before copying.</p>
169     *
170     * @param source SynchronizedDescriptiveStatistics to copy
171     * @param dest SynchronizedDescriptiveStatistics to copy to
172     * @throws NullArgumentException if either source or dest is null
173     */
174    public static void copy(SynchronizedDescriptiveStatistics source,
175                            SynchronizedDescriptiveStatistics dest)
176        throws NullArgumentException {
177        MathUtils.checkNotNull(source);
178        MathUtils.checkNotNull(dest);
179        synchronized (source) {
180            synchronized (dest) {
181                DescriptiveStatistics.copy(source, dest);
182            }
183        }
184    }
185}