Merge pull request #634 from mookkiah/issue_587_promise

#587SonarQube reports bugs in promise module
This commit is contained in:
Ilkka Seppälä 2017-09-24 18:42:36 +03:00 committed by GitHub
commit e80677b1f3
2 changed files with 25 additions and 26 deletions

View File

@ -65,7 +65,7 @@ public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class); private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private static final String DEFAULT_URL = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/Promise/promise/README.md"; private static final String DEFAULT_URL = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/promise/README.md";
private final ExecutorService executor; private final ExecutorService executor;
private final CountDownLatch stopLatch; private final CountDownLatch stopLatch;

View File

@ -27,11 +27,16 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* A really simplified implementation of future that allows completing it successfully with a value * A really simplified implementation of future that allows completing it successfully with a value
* or exceptionally with an exception. * or exceptionally with an exception.
*/ */
class PromiseSupport<T> implements Future<T> { class PromiseSupport<T> implements Future<T> {
private static final Logger LOGGER = LoggerFactory.getLogger(PromiseSupport.class);
private static final int RUNNING = 1; private static final int RUNNING = 1;
private static final int FAILED = 2; private static final int FAILED = 2;
@ -80,40 +85,34 @@ class PromiseSupport<T> implements Future<T> {
@Override @Override
public T get() throws InterruptedException, ExecutionException { public T get() throws InterruptedException, ExecutionException {
if (state == COMPLETED) { synchronized (lock) {
return value; while (state == RUNNING) {
} else if (state == FAILED) {
throw new ExecutionException(exception);
} else {
synchronized (lock) {
lock.wait(); lock.wait();
if (state == COMPLETED) {
return value;
} else {
throw new ExecutionException(exception);
}
} }
} }
if (state == COMPLETED) {
return value;
}
throw new ExecutionException(exception);
} }
@Override @Override
public T get(long timeout, TimeUnit unit) public T get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException { throws ExecutionException, TimeoutException {
if (state == COMPLETED) { synchronized (lock) {
return value; while (state == RUNNING) {
} else if (state == FAILED) { try {
throw new ExecutionException(exception); lock.wait(unit.toMillis(timeout));
} else { } catch (InterruptedException e) {
synchronized (lock) { LOGGER.warn("Interrupted!", e);
lock.wait(unit.toMillis(timeout)); Thread.currentThread().interrupt();
if (state == COMPLETED) {
return value;
} else if (state == FAILED) {
throw new ExecutionException(exception);
} else {
throw new TimeoutException();
} }
} }
} }
if (state == COMPLETED) {
return value;
}
throw new ExecutionException(exception);
} }
} }