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.math4.legacy.stat.descriptive;
018
019import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
020import org.apache.commons.math4.legacy.exception.NullArgumentException;
021
022/**
023 * Implementation of
024 * {@link org.apache.commons.math4.legacy.stat.descriptive.DescriptiveStatistics} that
025 * is safe to use in a multithreaded environment.  Multiple threads can safely
026 * operate on a single instance without causing runtime exceptions due to race
027 * conditions.  In effect, this implementation makes modification and access
028 * methods atomic operations for a single instance.  That is to say, as one
029 * thread is computing a statistic from the instance, no other thread can modify
030 * the instance nor compute another statistic.
031 *
032 * @since 1.2
033 */
034public class SynchronizedDescriptiveStatistics extends DescriptiveStatistics {
035    /**
036     * Construct an instance with infinite window.
037     */
038    public SynchronizedDescriptiveStatistics() {
039        // no try-catch or advertized IAE because arg is valid
040        this(INFINITE_WINDOW);
041    }
042
043    /**
044     * Construct an instance with finite window.
045     * @param window the finite window size.
046     * @throws MathIllegalArgumentException if window size is less than 1 but
047     * not equal to {@link #INFINITE_WINDOW}
048     */
049    public SynchronizedDescriptiveStatistics(int window) throws MathIllegalArgumentException {
050        super(window);
051    }
052
053    /**
054     * A copy constructor. Creates a deep-copy of the {@code original}.
055     *
056     * @param original the {@code SynchronizedDescriptiveStatistics} instance to copy
057     * @throws NullArgumentException if original is null
058     */
059    public SynchronizedDescriptiveStatistics(SynchronizedDescriptiveStatistics original)
060    throws NullArgumentException {
061        copy(original, this);
062    }
063
064    /**
065     * {@inheritDoc}
066     */
067    @Override
068    public synchronized void addValue(double v) {
069        super.addValue(v);
070    }
071
072    /**
073     * {@inheritDoc}
074     */
075    @Override
076    public synchronized double apply(UnivariateStatistic stat) {
077        return super.apply(stat);
078    }
079
080    /**
081     * {@inheritDoc}
082     */
083    @Override
084    public synchronized void clear() {
085        super.clear();
086    }
087
088    /**
089     * {@inheritDoc}
090     */
091    @Override
092    public synchronized double getElement(int index) {
093        return super.getElement(index);
094    }
095
096    /**
097     * {@inheritDoc}
098     */
099    @Override
100    public synchronized long getN() {
101        return super.getN();
102    }
103
104    /**
105     * {@inheritDoc}
106     */
107    @Override
108    public synchronized double getStandardDeviation() {
109        return super.getStandardDeviation();
110    }
111
112    /**
113     * {@inheritDoc}
114     */
115    @Override
116    public synchronized double getQuadraticMean() {
117        return super.getQuadraticMean();
118    }
119
120    /**
121     * {@inheritDoc}
122     */
123    @Override
124    public synchronized double[] getValues() {
125        return super.getValues();
126    }
127
128    /**
129     * {@inheritDoc}
130     */
131    @Override
132    public synchronized int getWindowSize() {
133        return super.getWindowSize();
134    }
135
136    /**
137     * {@inheritDoc}
138     */
139    @Override
140    public synchronized void setWindowSize(int windowSize) throws MathIllegalArgumentException {
141        super.setWindowSize(windowSize);
142    }
143
144    /**
145     * {@inheritDoc}
146     */
147    @Override
148    public synchronized String toString() {
149        return super.toString();
150    }
151
152    /**
153     * Returns a copy of this SynchronizedDescriptiveStatistics instance with the
154     * same internal state.
155     *
156     * @return a copy of this
157     */
158    @Override
159    public synchronized SynchronizedDescriptiveStatistics copy() {
160        SynchronizedDescriptiveStatistics result =
161            new SynchronizedDescriptiveStatistics();
162        // No try-catch or advertised exception because arguments are guaranteed non-null
163        copy(this, result);
164        return result;
165    }
166
167    /**
168     * Copies source to dest.
169     * <p>Neither source nor dest can be null.</p>
170     * <p>Acquires synchronization lock on source, then dest before copying.</p>
171     *
172     * @param source SynchronizedDescriptiveStatistics to copy
173     * @param dest SynchronizedDescriptiveStatistics to copy to
174     * @throws NullArgumentException if either source or dest is null
175     */
176    public static void copy(SynchronizedDescriptiveStatistics source,
177                            SynchronizedDescriptiveStatistics dest)
178        throws NullArgumentException {
179        NullArgumentException.check(source);
180        NullArgumentException.check(dest);
181        synchronized (source) {
182            synchronized (dest) {
183                DescriptiveStatistics.copy(source, dest);
184            }
185        }
186    }
187}