You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2019/09/27 13:49:12 UTC

[commons-rng] 02/05: Fix PMD errors in stress test code.

This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git

commit bf55f9444b38cda328cd1d9ca9731a65cc72922e
Author: aherbert <ah...@apache.org>
AuthorDate: Fri Sep 27 14:09:37 2019 +0100

    Fix PMD errors in stress test code.
---
 .../rng/examples/stress/BridgeTestCommand.java     |  18 ++-
 .../examples/stress/ExamplesStressApplication.java |   2 +-
 .../commons/rng/examples/stress/ListCommand.java   |   6 +-
 .../examples/stress/ManifestVersionProvider.java   |   2 +-
 .../commons/rng/examples/stress/OutputCommand.java |  35 +++--
 .../commons/rng/examples/stress/ProcessUtils.java  |   4 +-
 .../rng/examples/stress/ResultsCommand.java        | 141 ++++++++++++---------
 .../rng/examples/stress/StressTestCommand.java     | 126 ++++++++++--------
 8 files changed, 191 insertions(+), 143 deletions(-)

diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
index 311eff9..b0cc26e 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/BridgeTestCommand.java
@@ -87,7 +87,7 @@ class BridgeTestCommand implements Callable<Void> {
      * of the executable. Captures stdout of the executable to a file.
      */
     private void runBridgeTest() {
-        final ArrayList<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
+        final List<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
 
         try {
             final File dataFile = new File(fileOutputPrefix + ".data");
@@ -123,17 +123,17 @@ class BridgeTestCommand implements Callable<Void> {
                 }
             }
 
-            Integer exitValue = ProcessUtils.getExitValue(testingProcess);
-            if (exitValue != null) {
+            final Integer exitValue = ProcessUtils.getExitValue(testingProcess);
+            if (exitValue == null) {
+                LogUtils.error("%s did not exit. Process was killed.", command.get(0));
+            } else {
                 if (exitValue.intValue() != 0) {
                     LogUtils.error("%s exit code = %d", command.get(0), exitValue.intValue());
                 }
-            } else {
-                LogUtils.error("%s did not exit. Process was killed.", command.get(0));
             }
 
         } catch (IOException ex) {
-            throw new ApplicationException("Failed to run process: " + ex.getMessage());
+            throw new ApplicationException("Failed to run process: " + ex.getMessage(), ex);
         }
     }
 
@@ -154,9 +154,7 @@ class BridgeTestCommand implements Callable<Void> {
                                  int value,
                                  boolean littleEndian) throws IOException {
         OutputCommand.writeInt(textOutput, value);
-        if (littleEndian) {
-            value = Integer.reverseBytes(value);
-        }
-        dataOutput.writeInt(value);
+        final int binaryValue = littleEndian ? Integer.reverseBytes(value) : value;
+        dataOutput.writeInt(binaryValue);
     }
 }
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java
index 495dfec..83f7f2b 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ExamplesStressApplication.java
@@ -73,7 +73,7 @@ public final class ExamplesStressApplication {
         try {
             // Parse the command line and invokes the Callable program (RNGUtilities)
             cmd.parseWithHandler(new RunLast(), args);
-        } catch (final picocli.CommandLine.ExecutionException ex) {
+        } catch (final CommandLine.ExecutionException ex) {
             final Throwable cause = ex.getCause();
             if (cause != null) {
                 // If this was an exception generated by the application then the full
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java
index 5f774e4..16fa969 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ListCommand.java
@@ -167,10 +167,10 @@ class ListCommand implements Callable<Void> {
         format = String.format("%%-%ds   %%-%ds   ", idWidth + 2, randomSourceWidth);
         for (final StressTestData data : testData) {
             formatter.format(format, data.getId(), data.getRandomSource().name());
-            if (data.getArgs() != null) {
-                formatter.format("%-7d   %s", data.getTrials(), Arrays.toString(data.getArgs()));
-            } else {
+            if (data.getArgs() == null) {
                 appendable.append(Integer.toString(data.getTrials()));
+            } else {
+                formatter.format("%-7d   %s", data.getTrials(), Arrays.toString(data.getArgs()));
             }
             appendable.append(newLine);
         }
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java
index 52b55c9..608197d 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ManifestVersionProvider.java
@@ -36,7 +36,7 @@ class ManifestVersionProvider implements IVersionProvider {
     /** {@inheritDoc} */
     @Override
     public String[] getVersion() throws Exception {
-        final Enumeration<URL> resources = ManifestVersionProvider.class.getClassLoader()
+        final Enumeration<URL> resources = Thread.currentThread().getContextClassLoader()
                                            .getResources("META-INF/MANIFEST.MF");
         while (resources.hasMoreElements()) {
             final URL url = resources.nextElement();
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
index f5d46cb..6e15d3a 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/OutputCommand.java
@@ -28,8 +28,6 @@ import java.io.BufferedOutputStream;
 import java.io.BufferedWriter;
 import java.io.DataOutputStream;
 import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -37,6 +35,7 @@ import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Formatter;
 import java.util.List;
@@ -52,6 +51,10 @@ import java.util.concurrent.Callable;
 class OutputCommand implements Callable<Void> {
     /** The new line characters. */
     private static final String NEW_LINE = System.lineSeparator();
+    /** Character '['. */
+    private static final char LEFT_SQUARE_BRACKET = '[';
+    /** Character ']'. */
+    private static final char RIGHT_SQUARE_BRACKET = ']';
 
     /** Lookup table for binary representation of bytes. */
     private static final String[] BIT_REP = {
@@ -170,7 +173,7 @@ class OutputCommand implements Callable<Void> {
         // Strip these for convenience.
         stripArrayFormatting(arguments);
 
-        for (String argument : arguments) {
+        for (final String argument : arguments) {
             data.add(RNGUtils.parseArgument(argument));
         }
         try {
@@ -193,11 +196,11 @@ class OutputCommand implements Callable<Void> {
         if (size > 1) {
             // These will not be empty as they were created from command-line args.
             final String first = arguments.get(0);
-            if (first.charAt(0) == '[') {
+            if (first.charAt(0) == LEFT_SQUARE_BRACKET) {
                 arguments.set(0, first.substring(1));
             }
             final String last = arguments.get(size - 1);
-            if (last.charAt(last.length() - 1) == ']') {
+            if (last.charAt(last.length() - 1) == RIGHT_SQUARE_BRACKET) {
                 arguments.set(size - 1, last.substring(0, last.length() - 1));
             }
         }
@@ -217,8 +220,8 @@ class OutputCommand implements Callable<Void> {
     private OutputStream createOutputStream() {
         if (fileOutput != null) {
             try {
-                return new FileOutputStream(fileOutput);
-            } catch (FileNotFoundException ex) {
+                Files.newOutputStream(fileOutput.toPath());
+            } catch (IOException ex) {
                 throw new ApplicationException("Failed to create output: " + fileOutput, ex);
             }
         }
@@ -283,12 +286,11 @@ class OutputCommand implements Callable<Void> {
             output.write(NEW_LINE);
             output.write("numbit: 32");
             output.write(NEW_LINE);
-            while (count > 0) {
-                count--;
+            for (long c = 0; c < count; c++) {
                 // Unsigned integers
                 final String text = Long.toString(rng.nextInt() & 0xffffffffL);
                 // Left pad with spaces
-                for (int i = 10 - text.length(); i-- > 0;) {
+                for (int i = 10 - text.length(); i > 0; i--) {
                     output.write(' ');
                 }
                 output.write(text);
@@ -319,14 +321,12 @@ class OutputCommand implements Callable<Void> {
     static void writeBinaryIntData(final UniformRandomProvider rng,
                                    long count,
                                    final OutputStream out) throws IOException {
-        if (count < 1) {
-            // Effectively unlimited: program must be killed
-            count = Long.MAX_VALUE;
-        }
+        // If count is not positive use max value.
+        // This is effectively unlimited: program must be killed.
+        final long limit = (count < 1) ? Long.MAX_VALUE : count;
         try (DataOutputStream data = new DataOutputStream(
                 new BufferedOutputStream(out))) {
-            while (count > 0) {
-                count--;
+            for (long c = 0; c < limit; c++) {
                 data.writeInt(rng.nextInt());
             }
         }
@@ -347,8 +347,7 @@ class OutputCommand implements Callable<Void> {
         checkCount(count, OutputFormat.BITS);
 
         try (BufferedWriter output = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))) {
-            while (count > 0) {
-                count--;
+            for (long c = 0; c < count; c++) {
                 writeInt(output, rng.nextInt());
             }
         }
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java
index b07aab1..3c94cc0 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ProcessUtils.java
@@ -67,8 +67,8 @@ final class ProcessUtils {
      * @return the command
      * @throws ApplicationException If the executable path cannot be resolved
      */
-    static ArrayList<String> buildSubProcessCommand(File executable,
-                                                    List<String> executableArguments) {
+    static List<String> buildSubProcessCommand(File executable,
+                                               List<String> executableArguments) {
         final ArrayList<String> command = new ArrayList<>();
         try {
             command.add(executable.getCanonicalPath());
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java
index a564617..2f20252 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/ResultsCommand.java
@@ -26,8 +26,6 @@ import picocli.CommandLine.Parameters;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -80,6 +78,12 @@ class ResultsCommand implements Callable<Void> {
     private static final String DIEHARDER_SUMS = "diehard_sums";
     /** The string identifying a bit-reversed generator. */
     private static final String BIT_REVERSED = "Bit-reversed";
+    /** Character '\'. */
+    private static final char FORWARD_SLASH = '\\';
+    /** Character '/'. */
+    private static final char BACK_SLASH = '\\';
+    /** Character '|'. */
+    private static final char PIPE = '|';
 
     /** The standard options. */
     @Mixin
@@ -154,7 +158,7 @@ class ResultsCommand implements Callable<Void> {
         /** The test application format. */
         private final TestFormat testFormat;
         /** The names of the failed tests. */
-        private final ArrayList<String> failedTests = new ArrayList<>();
+        private final List<String> failedTests = new ArrayList<>();
         /** The test application name. */
         private String testApplicationName;
         /** Flag to indicate results are complete (i.e. not still in progress). */
@@ -226,7 +230,7 @@ class ResultsCommand implements Callable<Void> {
          *
          * @return the failed tests
          */
-        ArrayList<String> getFailedTests() {
+        List<String> getFailedTests() {
             return failedTests;
         }
 
@@ -263,7 +267,7 @@ class ResultsCommand implements Callable<Void> {
          * @return the test application name
          */
         String getTestApplicationName() {
-            return testApplicationName != null ? testApplicationName : getTestFormat().toString();
+            return testApplicationName == null ? getTestFormat().toString() : testApplicationName;
         }
 
         /**
@@ -309,7 +313,7 @@ class ResultsCommand implements Callable<Void> {
             default:
                 throw new ApplicationException("Unknown output format: " + outputFormat);
             }
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             throw new ApplicationException("IO error: " + ex.getMessage(), ex);
         }
         return null;
@@ -322,7 +326,7 @@ class ResultsCommand implements Callable<Void> {
      */
     private List<TestResult> readResults() {
         final ArrayList<TestResult> results = new ArrayList<>();
-        for (File resultFile : resultsFiles) {
+        for (final File resultFile : resultsFiles) {
             readResults(results, resultFile);
         }
         return results;
@@ -336,13 +340,13 @@ class ResultsCommand implements Callable<Void> {
      */
     private void readResults(List<TestResult> results,
                              File resultFile) {
-        final ArrayList<String> contents = readFileContents(resultFile);
+        final List<String> contents = readFileContents(resultFile);
         // Files may have multiple test results per file (i.e. appended output)
         final List<List<String>> outputs = splitContents(contents);
         if (outputs.isEmpty()) {
-            LogUtils.error("No test output in file: " + resultFile);
+            LogUtils.error("No test output in file: %s", resultFile);
         } else {
-            for (List<String> testOutput : outputs) {
+            for (final List<String> testOutput : outputs) {
                 results.add(readResult(resultFile, testOutput));
             }
         }
@@ -355,14 +359,13 @@ class ResultsCommand implements Callable<Void> {
      * @return the file contents
      * @throws ApplicationException If the file cannot be read.
      */
-    private static ArrayList<String> readFileContents(File resultFile) {
+    private static List<String> readFileContents(File resultFile) {
         final ArrayList<String> contents = new ArrayList<>();
         try (BufferedReader reader = Files.newBufferedReader(resultFile.toPath())) {
-            String line;
-            while ((line = reader.readLine()) != null) {
+            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                 contents.add(line);
             }
-        } catch (IOException ex) {
+        } catch (final IOException ex) {
             throw new ApplicationException("Failed to read file contents: " + resultFile, ex);
         }
         return contents;
@@ -544,8 +547,8 @@ class ResultsCommand implements Callable<Void> {
         // Note:
         // This will count sub-parts of the same test as distinct failures.
         while (iter.hasNext()) {
-            String line = iter.next();
-            Matcher matcher = TESTU01_TEST_RESULT_PATTERN.matcher(line);
+            final String line = iter.next();
+            final Matcher matcher = TESTU01_TEST_RESULT_PATTERN.matcher(line);
             if (matcher.find()) {
                 testResult.addFailedTest(matcher.group(1).trim());
             } else if (TEST_DURATION_PATTERN.matcher(line).find()) {
@@ -580,8 +583,8 @@ class ResultsCommand implements Callable<Void> {
     private OutputStream createOutputStream() {
         if (fileOutput != null) {
             try {
-                return new FileOutputStream(fileOutput);
-            } catch (FileNotFoundException ex) {
+                Files.newOutputStream(fileOutput.toPath());
+            } catch (final IOException ex) {
                 throw new ApplicationException("Failed to create output: " + fileOutput, ex);
             }
         }
@@ -674,8 +677,8 @@ class ResultsCommand implements Callable<Void> {
                 .append(result.getFailureCountString()).append("}}");
             // Convert to web-link name separators
             for (int i = 0; i < sb.length(); i++) {
-                if (sb.charAt(i) == '\\') {
-                    sb.setCharAt(i, '/');
+                if (sb.charAt(i) == BACK_SLASH) {
+                    sb.setCharAt(i, FORWARD_SLASH);
                 }
             }
             return sb.toString();
@@ -697,14 +700,14 @@ class ResultsCommand implements Callable<Void> {
             output.write(separator);
 
             // This will collate results for each combination of 'RandomSource + bitReversed'
-            for (RandomSource randomSource : randomSources) {
-                for (boolean reversed : bitReversed) {
+            for (final RandomSource randomSource : randomSources) {
+                for (final boolean reversed : bitReversed) {
                     output.write('|');
                     writeAPTColumn(output, randomSource.toString());
                     if (showBitReversedColumn) {
                         writeAPTColumn(output, Boolean.toString(reversed));
                     }
-                    for (String testName : testNames) {
+                    for (final String testName : testNames) {
                         final List<TestResult> testResults = getTestResults(results, randomSource, reversed, testName);
                         writeAPTColumn(output, testResults.stream()
                                                           .map(toAPTString)
@@ -725,7 +728,7 @@ class ResultsCommand implements Callable<Void> {
      */
     private static List<RandomSource> getRandomSources(List<TestResult> results) {
         final EnumSet<RandomSource> set = EnumSet.noneOf(RandomSource.class);
-        for (TestResult result : results) {
+        for (final TestResult result : results) {
             set.add(result.getRandomSource());
         }
         final ArrayList<RandomSource> list = new ArrayList<>(set);
@@ -741,18 +744,18 @@ class ResultsCommand implements Callable<Void> {
      */
     private static List<Boolean> getBitReversed(List<TestResult> results) {
         final ArrayList<Boolean> list = new ArrayList<>(2);
-        if (!results.isEmpty()) {
+        if (results.isEmpty()) {
+            // Default to no bit-reversed results
+            list.add(Boolean.FALSE);
+        } else {
             final boolean first = results.get(0).isBitReversed();
             list.add(first);
-            for (TestResult result : results) {
+            for (final TestResult result : results) {
                 if (first != result.isBitReversed()) {
                     list.add(!first);
                     break;
                 }
             }
-        } else {
-            // Default to no bit-reversed results
-            list.add(Boolean.FALSE);
         }
         Collections.sort(list);
         return list;
@@ -766,7 +769,7 @@ class ResultsCommand implements Callable<Void> {
      */
     private static List<String> getTestNames(List<TestResult> results) {
         final HashSet<String> set = new HashSet<>();
-        for (TestResult result : results) {
+        for (final TestResult result : results) {
             set.add(result.getTestApplicationName());
         }
         final ArrayList<String> list = new ArrayList<>(set);
@@ -808,7 +811,7 @@ class ResultsCommand implements Callable<Void> {
      */
     private static String getPathPrefix(TestResult testResult) {
         final String parent = testResult.getResultFile().getParent();
-        return parent != null ? parent : "";
+        return parent == null ? "" : parent;
     }
 
     /**
@@ -820,11 +823,11 @@ class ResultsCommand implements Callable<Void> {
      */
     private static String createAPTHeader(boolean showBitReversedColumn,
                                           List<String> testNames) {
-        final StringBuilder sb = new StringBuilder("|| RNG identifier ||");
+        final StringBuilder sb = new StringBuilder(100).append("|| RNG identifier ||");
         if (showBitReversedColumn) {
-            sb.append(' ').append("Bit-reversed ||");
+            sb.append(" Bit-reversed ||");
         }
-        for (String name : testNames) {
+        for (final String name : testNames) {
             sb.append(' ').append(name).append(" ||");
         }
         return sb.toString();
@@ -843,7 +846,7 @@ class ResultsCommand implements Callable<Void> {
         // character, "+-" for all other occurrences except "-+" at the end
         final StringBuilder sb = new StringBuilder(header);
         for (int i = 0; i < header.length(); i++) {
-            if (sb.charAt(i) == '|') {
+            if (sb.charAt(i) == PIPE) {
                 sb.setCharAt(i, i == 0 ? '*' : '+');
                 sb.setCharAt(i + 1,  '-');
             } else {
@@ -885,7 +888,7 @@ class ResultsCommand implements Callable<Void> {
                                                    boolean bitReversed,
                                                    String testName) {
         final ArrayList<TestResult> list = new ArrayList<>();
-        for (TestResult result : results) {
+        for (final TestResult result : results) {
             if (result.getRandomSource() == randomSource &&
                 result.bitReversed == bitReversed &&
                 result.getTestApplicationName().equals(testName)) {
@@ -914,14 +917,7 @@ class ResultsCommand implements Callable<Void> {
         // Make bit-reversed column optional if no generators are bit reversed.
         final boolean showBitReversedColumn = bitReversed.contains(Boolean.TRUE);
 
-        final ArrayList<List<String>> columns = new ArrayList<>();
-        columns.add(createColumn("RNG"));
-        if (showBitReversedColumn) {
-            columns.add(createColumn(BIT_REVERSED));
-        }
-        for (String testName : testNames) {
-            columns.add(createColumn(testName));
-        }
+        final List<List<String>> columns = createColumns(testNames, showBitReversedColumn);
 
         // Add all data
         // This will collate results for each combination of 'RandomSource + bitReversed'
@@ -932,7 +928,7 @@ class ResultsCommand implements Callable<Void> {
                 if (showBitReversedColumn) {
                     columns.get(i++).add(Boolean.toString(reversed));
                 }
-                for (String testName : testNames) {
+                for (final String testName : testNames) {
                     final List<TestResult> testResults = getTestResults(results, randomSource,
                             reversed, testName);
                     columns.get(i++).add(testResults.stream()
@@ -943,17 +939,7 @@ class ResultsCommand implements Callable<Void> {
         }
 
         // Create format using the column widths
-        final StringBuilder sb = new StringBuilder();
-        try (Formatter formatter = new Formatter(sb)) {
-            for (int i = 0; i < columns.size(); i++) {
-                if (i != 0) {
-                    sb.append('\t');
-                }
-                formatter.format("%%-%ds", getColumnWidth(columns.get(i)));
-            }
-        }
-        sb.append(System.lineSeparator());
-        final String format = sb.toString();
+        final String format = createTextFormatFromColumnWidths(columns);
 
         // Output
         try (BufferedWriter output = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
@@ -970,6 +956,26 @@ class ResultsCommand implements Callable<Void> {
     }
 
     /**
+     * Creates the columns.
+     *
+     * @param testNames the test names
+     * @param showBitReversedColumn Set to true to show the bit reversed column
+     * @return the list of columns
+     */
+    private static List<List<String>> createColumns(final List<String> testNames,
+        final boolean showBitReversedColumn) {
+        final ArrayList<List<String>> columns = new ArrayList<>();
+        columns.add(createColumn("RNG"));
+        if (showBitReversedColumn) {
+            columns.add(createColumn(BIT_REVERSED));
+        }
+        for (final String testName : testNames) {
+            columns.add(createColumn(testName));
+        }
+        return columns;
+    }
+
+    /**
      * Creates the column.
      *
      * @param columnName Column name.
@@ -981,6 +987,27 @@ class ResultsCommand implements Callable<Void> {
         return list;
     }
 
+
+    /**
+     * Creates the text format from column widths.
+     *
+     * @param columns Columns.
+     * @return the text format string
+     */
+    private static String createTextFormatFromColumnWidths(final List<List<String>> columns) {
+        final StringBuilder sb = new StringBuilder();
+        try (Formatter formatter = new Formatter(sb)) {
+            for (int i = 0; i < columns.size(); i++) {
+                if (i != 0) {
+                    sb.append('\t');
+                }
+                formatter.format("%%-%ds", getColumnWidth(columns.get(i)));
+            }
+        }
+        sb.append(System.lineSeparator());
+        return sb.toString();
+    }
+
     /**
      * Gets the column width using the maximum length of the column items.
      *
@@ -989,7 +1016,7 @@ class ResultsCommand implements Callable<Void> {
      */
     private static int getColumnWidth(List<String> column) {
         int width = 0;
-        for (String text : column) {
+        for (final String text : column) {
             width = Math.max(width, text.length());
         }
         return width;
diff --git a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
index 9eaa405..2bc87fd 100644
--- a/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
+++ b/commons-rng-examples/examples-stress/src/main/java/org/apache/commons/rng/examples/stress/StressTestCommand.java
@@ -44,6 +44,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * Specification for the "stress" command.
@@ -57,6 +58,9 @@ import java.util.concurrent.TimeUnit;
          description = {"Run repeat trials of random data generators using a provided test application.",
                         "Data is transferred to the application sub-process via standard input."})
 class StressTestCommand implements Callable<Void> {
+    /** 1000. Any value below this can be exactly represented to 3 significant figures. */
+    private static final int ONE_THOUSAND = 1000;
+
     /** The standard options. */
     @Mixin
     private StandardOptions reusableOptions;
@@ -160,11 +164,16 @@ class StressTestCommand implements Callable<Void> {
     @Option(names = {"--dry-run"},
             description = "Perform a dry run where the generators and output files are created " +
                           "but the stress test is not executed.")
-    private boolean dryRun = false;
+    private boolean dryRun;
 
-    /** The stop file exists flag. This is set in a synchronised method. */
+    /** The locl to hold when checking the stop file. */
+    private ReentrantLock stopFileLock = new ReentrantLock(false);
+    /** The stop file exists flag. This should be read/updated when holding the lock. */
     private boolean stopFileExists;
-    /** The timestamp when the stop file was last checked. */
+    /**
+     * The timestamp when the stop file was last checked.
+     * This should be read/updated when holding the lock.
+     */
     private long stopFileTimestamp;
 
     /**
@@ -215,26 +224,41 @@ class StressTestCommand implements Callable<Void> {
     /**
      * Check if the stop file exists.
      *
-     * <p>This method is synchronized. It will log a message if the file exists one time only.
+     * <p>This method is thread-safe. It will log a message if the file exists one time only.
      *
      * @return true if the stop file exists
      */
-    private synchronized boolean stopFileExists() {
-        if (!stopFileExists) {
-            // This should hit the filesystem each time it is called.
-            // To prevent this happening a lot when all the first set of tasks run use
-            // a timestamp to limit the check to 1 time each interval.
-            final long timestamp = System.currentTimeMillis();
-            if (timestamp > stopFileTimestamp) {
-                stopFileTimestamp = timestamp + TimeUnit.SECONDS.toMillis(2);
-                stopFileExists = stopFile.exists();
-                if (stopFileExists) {
-                    LogUtils.info("Stop file detected: " + stopFile);
-                    LogUtils.info("No further tasks will start");
+    private boolean isStopFileExists() {
+        stopFileLock.lock();
+        try {
+            if (!stopFileExists) {
+                // This should hit the filesystem each time it is called.
+                // To prevent this happening a lot when all the first set of tasks run use
+                // a timestamp to limit the check to 1 time each interval.
+                final long timestamp = System.currentTimeMillis();
+                if (timestamp > stopFileTimestamp) {
+                    checkStopFile(timestamp);
                 }
             }
+            return stopFileExists;
+        } finally {
+            stopFileLock.unlock();
+        }
+    }
+
+    /**
+     * Check if the stop file exists. Update the timestamp for the next check. If the stop file
+     * does exists then log a message.
+     *
+     * @param timestamp Timestamp of the last check.
+     */
+    private void checkStopFile(final long timestamp) {
+        stopFileTimestamp = timestamp + TimeUnit.SECONDS.toMillis(2);
+        stopFileExists = stopFile.exists();
+        if (stopFileExists) {
+            LogUtils.info("Stop file detected: %s", stopFile);
+            LogUtils.info("No further tasks will start");
         }
-        return stopFileExists;
     }
 
     /**
@@ -282,14 +306,14 @@ class StressTestCommand implements Callable<Void> {
      * @param stressTestData List of generators to be tested.
      */
     private void runStressTest(Iterable<StressTestData> stressTestData) {
-        final ArrayList<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
+        final List<String> command = ProcessUtils.buildSubProcessCommand(executable, executableArguments);
 
         // Check existing output files before starting the tasks.
         final String basePath = fileOutputPrefix.getAbsolutePath();
         checkExistingOutputFiles(basePath, stressTestData);
 
         LogUtils.info("Running stress test ...");
-        LogUtils.info("Shutdown by creating stop file: " + stopFile);
+        LogUtils.info("Shutdown by creating stop file: %s",  stopFile);
         final ProgressTracker progressTracker = new ProgressTracker(countTrials(stressTestData));
 
         // Run tasks with parallel execution.
@@ -398,7 +422,7 @@ class StressTestCommand implements Callable<Void> {
      */
     private void submitTasks(ExecutorService service,
                              List<Future<?>> taskList,
-                             ArrayList<String> command,
+                             List<String> command,
                              String basePath,
                              StressTestData testData,
                              ProgressTracker progressTracker) {
@@ -472,9 +496,11 @@ class StressTestCommand implements Callable<Void> {
         /**
          * Increment the progress.
          */
-        synchronized void incrementProgress() {
-            count++;
-            showProgress();
+        void incrementProgress() {
+            synchronized (this) {
+                count++;
+                showProgress();
+            }
         }
 
         /**
@@ -558,7 +584,7 @@ class StressTestCommand implements Callable<Void> {
         /** {@inheritDoc} */
         @Override
         public void run() {
-            if (cmd.stopFileExists()) {
+            if (cmd.isStopFileExists()) {
                 // Do nothing
                 return;
             }
@@ -609,7 +635,7 @@ class StressTestCommand implements Callable<Void> {
                     sink.writeInt(rng.nextInt());
                     numbersUsed++;
                 }
-            } catch (final IOException e) {
+            } catch (final IOException ignored) {
                 // Hopefully getting here when the analyzing software terminates.
             }
 
@@ -624,33 +650,32 @@ class StressTestCommand implements Callable<Void> {
          * {@code output} file.
          */
         private void printHeader() throws IOException {
-            final StringBuilder sb = new StringBuilder();
-            sb.append(C).append(N);
-            sb.append(C).append("RandomSource: ").append(randomSource.name()).append(N);
-            sb.append(C).append("RNG: ").append(rng.toString()).append(N);
-            sb.append(C).append("Seed: ").append(RNGUtils.encodeHex(seed)).append(N);
-            sb.append(C).append(N);
+            final StringBuilder sb = new StringBuilder(200);
+            sb.append(C).append(N)
+                .append(C).append("RandomSource: ").append(randomSource.name()).append(N)
+                .append(C).append("RNG: ").append(rng.toString()).append(N)
+                .append(C).append("Seed: ").append(RNGUtils.encodeHex(seed)).append(N)
+                .append(C).append(N)
 
             // Match the output of 'java -version', e.g.
             // java version "1.8.0_131"
             // Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
             // Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
-            sb.append(C).append("Java: ").append(System.getProperty("java.version")).append(N);
+            .append(C).append("Java: ").append(System.getProperty("java.version")).append(N);
             appendNameAndVersion(sb, "Runtime", "java.runtime.name", "java.runtime.version");
             appendNameAndVersion(sb, "JVM", "java.vm.name", "java.vm.version", "java.vm.info");
 
             sb.append(C).append("OS: ").append(System.getProperty("os.name"))
                 .append(' ').append(System.getProperty("os.version"))
-                .append(' ').append(System.getProperty("os.arch")).append(N);
-            sb.append(C).append("Native byte-order: ").append(ByteOrder.nativeOrder()).append(N);
-            sb.append(C).append(N);
-
-            sb.append(C).append("Analyzer: ");
+                .append(' ').append(System.getProperty("os.arch")).append(N)
+                .append(C).append("Native byte-order: ").append(ByteOrder.nativeOrder()).append(N)
+                .append(C).append(N)
+                .append(C).append("Analyzer: ");
             for (final String s : command) {
                 sb.append(s).append(' ');
             }
-            sb.append(N);
-            sb.append(C).append(N);
+            sb.append(N)
+              .append(C).append(N);
 
             appendDate(sb, "Start").append(C).append(N);
 
@@ -667,21 +692,20 @@ class StressTestCommand implements Callable<Void> {
          */
         private void printFooter(long nanoTime,
                                  Object exitValue) throws IOException {
-            final StringBuilder sb = new StringBuilder();
+            final StringBuilder sb = new StringBuilder(200);
             sb.append(C).append(N);
 
             appendDate(sb, "End").append(C).append(N);
 
-            sb.append(C).append("Exit value: ").append(exitValue).append(N);
-            sb.append(C).append("Numbers used: ").append(numbersUsed)
-                        .append(" >= 2^").append(log2(numbersUsed))
-                        .append(" (").append(bytesToString(numbersUsed * 4)).append(')').append(N);
-            sb.append(C).append(N);
+            sb.append(C).append("Exit value: ").append(exitValue).append(N)
+                .append(C).append("Numbers used: ").append(numbersUsed)
+                          .append(" >= 2^").append(log2(numbersUsed))
+                          .append(" (").append(bytesToString(numbersUsed * 4)).append(')').append(N)
+                .append(C).append(N);
 
             final double duration = nanoTime * 1e-9 / 60;
-            sb.append(C).append("Test duration: ").append(duration).append(" minutes").append(N);
-
-            sb.append(C).append(N);
+            sb.append(C).append("Test duration: ").append(duration).append(" minutes").append(N)
+                .append(C).append(N);
 
             write(sb, output, true);
         }
@@ -726,7 +750,7 @@ class StressTestCommand implements Callable<Void> {
                 .append(System.getProperty(nameKey, "?"))
                 .append(" (build ")
                 .append(System.getProperty(versionKey, "?"));
-            for (String key : infoKeys) {
+            for (final String key : infoKeys) {
                 final String value = System.getProperty(key, "");
                 if (!value.isEmpty()) {
                     sb.append(", ").append(value);
@@ -748,7 +772,7 @@ class StressTestCommand implements Callable<Void> {
         private static StringBuilder appendDate(StringBuilder sb,
                                                 String prefix) {
             // Use local date format. It is not thread safe.
-            final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+            final SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US);
             return appendPrefix(sb, prefix).append(dateFormat.format(new Date())).append(N);
         }
 
@@ -796,7 +820,7 @@ class StressTestCommand implements Callable<Void> {
          */
         static String bytesToString(long bytes) {
             // When using the smallest unit no decimal point is needed, because it's the exact number.
-            if (bytes < 1000) {
+            if (bytes < ONE_THOUSAND) {
                 return bytes + " " + SI_UNITS[0];
             }