Avoid synchronizing on this and use an internal monitor instead

Where possible, code that previously synchronized on this (or on the
class in the case of static methods) has been updated to use an
internal monitor object instead. This allows the locking model that's
employed to be an implementation detail rather than part of the
class's API.

Classes that override a synchronized method continue to declare
the overriding method as synchronized. This ensures that locking
is consistent across the superclass and its subclass.

Closes gh-6262
This commit is contained in:
Andy Wilkinson
2016-07-01 10:00:29 +01:00
parent f9c7db1137
commit 92bb24e365
25 changed files with 685 additions and 511 deletions

View File

@@ -426,6 +426,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
*/
class IsolatedThreadGroup extends ThreadGroup {
private final Object monitor = new Object();
private Throwable exception;
IsolatedThreadGroup(String name) {
@@ -435,18 +437,21 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!(ex instanceof ThreadDeath)) {
synchronized (this) {
synchronized (this.monitor) {
this.exception = (this.exception == null ? ex : this.exception);
}
getLog().warn(ex);
}
}
public synchronized void rethrowUncaughtException()
throws MojoExecutionException {
if (this.exception != null) {
throw new MojoExecutionException("An exception occurred while running. "
+ this.exception.getMessage(), this.exception);
public void rethrowUncaughtException() throws MojoExecutionException {
synchronized (this.monitor) {
if (this.exception != null) {
throw new MojoExecutionException(
"An exception occurred while running. "
+ this.exception.getMessage(),
this.exception);
}
}
}