/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.catalina.valves;
/** * Some simple micro-benchmarks to help determine best approach for thread safety in valves, particularly the * {@link AccessLogValve}. Implemented as JUnit tests to make the simple to execute but does not used Test* as the class * name to avoid being included in the automated unit tests.
*/ publicclass Benchmarks {
@Test publicvoid testAccessLogGetDate() throws Exception { // Is it better to use a sync or a thread local here?
BenchmarkTest benchmark = new BenchmarkTest();
Runnable[] tests = new Runnable[] { new GetDateBenchmarkTest_Sync(), new GetDateBenchmarkTest_Local(), new GetDateBenchmarkTest_LocalMutableLong(), new GetDateBenchmarkTest_LocalStruct() };
benchmark.doTest(5, tests);
}
public Date getCurrentDate() {
Struct struct = currentStruct.get(); long systime = System.currentTimeMillis(); if ((systime - struct.currentMillis) > 1000) {
struct.currentDate = new Date(systime);
struct.currentMillis = systime;
} return struct.currentDate;
}
}
@Test publicvoid testAccessLogTimeDateElement() throws Exception { // Is it better to use a sync or a thread local here?
BenchmarkTest benchmark = new BenchmarkTest();
Runnable[] tests = new Runnable[] { new TimeDateElementBenchmarkTest_Sync(), new TimeDateElementBenchmarkTest_Local(), new TimeDateElementBenchmarkTest_LocalStruct(), new TimeDateElementBenchmarkTest_LocalStruct_SBuilder() };
benchmark.doTest(5, tests);
}
@Override public String toString() { return"single ThreadLocal";
}
privatestaticclass Struct { public String currentDateString; public Date currentDate = new Date(); public SimpleDateFormat dayFormatter = new SimpleDateFormat("dd"); public SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); public SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); public SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss");
}
@Override public String toString() { return"single ThreadLocal, with StringBuilder";
}
privatestaticclass Struct { public String currentDateString; public Date currentDate = new Date(); public SimpleDateFormat dayFormatter = new SimpleDateFormat("dd"); public SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); public SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy"); public SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm:ss");
}
privatevoid doTestInternal(int threadCount, int iterations, Runnable test) throws Exception { long start = System.currentTimeMillis(); Thread[] threads = newThread[threadCount]; for (int i = 0; i < threadCount; i++) {
threads[i] = newThread(new TestThread(iterations, test));
} for (int i = 0; i < threadCount; i++) {
threads[i].start();
} for (int i = 0; i < threadCount; i++) {
threads[i].join();
} long end = System.currentTimeMillis();
System.out.println(test.getClass().getSimpleName() + ": " + threadCount + " threads and " + iterations + " iterations using " + test + " took " + (end - start) + "ms");
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.