Work on #403, incorporate review changes
This commit is contained in:
parent
e7be94d2e4
commit
76970633b8
@ -3,10 +3,11 @@ layout: pattern
|
|||||||
title: Promise
|
title: Promise
|
||||||
folder: promise
|
folder: promise
|
||||||
permalink: /patterns/promise/
|
permalink: /patterns/promise/
|
||||||
categories: Structural
|
categories: Concurrency
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Java
|
||||||
- Concurrency
|
- Functional
|
||||||
|
- Reactive
|
||||||
- Difficulty-Intermediate
|
- Difficulty-Intermediate
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -74,38 +74,38 @@
|
|||||||
<operations public="true" package="true" protected="true" private="false" static="true"/>
|
<operations public="true" package="true" protected="true" private="false" static="true"/>
|
||||||
</display>
|
</display>
|
||||||
</class>
|
</class>
|
||||||
<realization id="9">
|
<generalization id="9">
|
||||||
<end type="SOURCE" refId="3"/>
|
|
||||||
<end type="TARGET" refId="2"/>
|
|
||||||
</realization>
|
|
||||||
<dependency id="10">
|
|
||||||
<end type="SOURCE" refId="8"/>
|
|
||||||
<end type="TARGET" refId="1"/>
|
|
||||||
</dependency>
|
|
||||||
<generalization id="11">
|
|
||||||
<end type="SOURCE" refId="1"/>
|
<end type="SOURCE" refId="1"/>
|
||||||
<end type="TARGET" refId="3"/>
|
<end type="TARGET" refId="3"/>
|
||||||
</generalization>
|
</generalization>
|
||||||
<dependency id="12">
|
<realization id="10">
|
||||||
<end type="SOURCE" refId="1"/>
|
<end type="SOURCE" refId="3"/>
|
||||||
<end type="TARGET" refId="4"/>
|
<end type="TARGET" refId="2"/>
|
||||||
</dependency>
|
</realization>
|
||||||
<dependency id="13">
|
<dependency id="11">
|
||||||
<end type="SOURCE" refId="1"/>
|
|
||||||
<end type="TARGET" refId="7"/>
|
|
||||||
</dependency>
|
|
||||||
<dependency id="14">
|
|
||||||
<end type="SOURCE" refId="8"/>
|
|
||||||
<end type="TARGET" refId="4"/>
|
|
||||||
</dependency>
|
|
||||||
<dependency id="15">
|
|
||||||
<end type="SOURCE" refId="1"/>
|
<end type="SOURCE" refId="1"/>
|
||||||
<end type="TARGET" refId="6"/>
|
<end type="TARGET" refId="6"/>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency id="16">
|
<dependency id="12">
|
||||||
|
<end type="SOURCE" refId="8"/>
|
||||||
|
<end type="TARGET" refId="1"/>
|
||||||
|
</dependency>
|
||||||
|
<dependency id="13">
|
||||||
|
<end type="SOURCE" refId="8"/>
|
||||||
|
<end type="TARGET" refId="4"/>
|
||||||
|
</dependency>
|
||||||
|
<dependency id="14">
|
||||||
|
<end type="SOURCE" refId="1"/>
|
||||||
|
<end type="TARGET" refId="7"/>
|
||||||
|
</dependency>
|
||||||
|
<dependency id="15">
|
||||||
<end type="SOURCE" refId="1"/>
|
<end type="SOURCE" refId="1"/>
|
||||||
<end type="TARGET" refId="5"/>
|
<end type="TARGET" refId="5"/>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency id="16">
|
||||||
|
<end type="SOURCE" refId="1"/>
|
||||||
|
<end type="TARGET" refId="4"/>
|
||||||
|
</dependency>
|
||||||
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
sort-features="false" accessors="true" visibility="true">
|
sort-features="false" accessors="true" visibility="true">
|
||||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
|
@ -22,6 +22,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.iluwatar.promise;
|
package com.iluwatar.promise;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@ -44,6 +53,8 @@ import java.util.concurrent.Executors;
|
|||||||
* <li> Prevents callback hell and provides callback aggregation
|
* <li> Prevents callback hell and provides callback aggregation
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
* @see CompletableFuture
|
* @see CompletableFuture
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
@ -68,23 +79,57 @@ public class App {
|
|||||||
|
|
||||||
private static void promiseUsage(Executor executor)
|
private static void promiseUsage(Executor executor)
|
||||||
throws InterruptedException, ExecutionException {
|
throws InterruptedException, ExecutionException {
|
||||||
Promise<Integer> consumedPromise = new Promise<>();
|
String urlString = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/Promise/promise/README.md";
|
||||||
consumedPromise.fulfillInAsync(() -> {
|
Promise<Integer> lineCountPromise = new Promise<String>().fulfillInAsync(() -> {
|
||||||
Thread.sleep(1000);
|
return downloadFile(urlString);
|
||||||
return 10;
|
}, executor).then(fileLocation -> {
|
||||||
}, executor).then(value -> {
|
return countLines(fileLocation);
|
||||||
System.out.println("Consumed int value: " + value);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Promise<String> transformedPromise = new Promise<>();
|
Promise<Map<Character, Integer>> charFrequencyPromise = new Promise<String>().fulfillInAsync(() -> {
|
||||||
transformedPromise.fulfillInAsync(() -> {
|
return String.valueOf(downloadFile(urlString));
|
||||||
Thread.sleep(1000);
|
}, executor).then(fileLocation -> {
|
||||||
return "10";
|
return characterFrequency(fileLocation);
|
||||||
}, executor).then(value -> { return Integer.parseInt(value); }).then(value -> {
|
|
||||||
System.out.println("Consumed transformed int value: " + value);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
consumedPromise.get();
|
lineCountPromise.get();
|
||||||
transformedPromise.get();
|
System.out.println("Line count is: " + lineCountPromise.get());
|
||||||
|
charFrequencyPromise.get();
|
||||||
|
System.out.println("Char frequency is: " + charFrequencyPromise.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Character, Integer> characterFrequency(String fileLocation) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Integer countLines(String fileLocation) {
|
||||||
|
int lineCount = 0;
|
||||||
|
try (Reader reader = new FileReader(fileLocation);
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(reader);) {
|
||||||
|
for (String line; (line = bufferedReader.readLine()) != null; ) {
|
||||||
|
lineCount++;
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return lineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String downloadFile(String urlString) throws InterruptedException, IOException {
|
||||||
|
URL url = new URL(urlString);
|
||||||
|
File file = File.createTempFile("promise_pattern", null);
|
||||||
|
try (Reader reader = new InputStreamReader(url.openStream());
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(reader);
|
||||||
|
FileWriter writer = new FileWriter(file)) {
|
||||||
|
for (String line; (line = bufferedReader.readLine()) != null; ) {
|
||||||
|
writer.write(line);
|
||||||
|
writer.write("\n");
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.println("File downloaded at: " + file.getAbsolutePath());
|
||||||
|
return file.getAbsolutePath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,11 +120,11 @@ public class Promise<T> extends PromiseSupport<T> {
|
|||||||
*/
|
*/
|
||||||
private class ConsumeAction implements Runnable {
|
private class ConsumeAction implements Runnable {
|
||||||
|
|
||||||
private Promise<T> src;
|
private final Promise<T> src;
|
||||||
private Promise<Void> dest;
|
private final Promise<Void> dest;
|
||||||
private Consumer<? super T> action;
|
private final Consumer<? super T> action;
|
||||||
|
|
||||||
ConsumeAction(Promise<T> src, Promise<Void> dest, Consumer<? super T> action) {
|
private ConsumeAction(Promise<T> src, Promise<Void> dest, Consumer<? super T> action) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
@ -147,11 +147,11 @@ public class Promise<T> extends PromiseSupport<T> {
|
|||||||
*/
|
*/
|
||||||
private class TransformAction<V> implements Runnable {
|
private class TransformAction<V> implements Runnable {
|
||||||
|
|
||||||
private Promise<T> src;
|
private final Promise<T> src;
|
||||||
private Promise<V> dest;
|
private final Promise<V> dest;
|
||||||
private Function<? super T, V> func;
|
private final Function<? super T, V> func;
|
||||||
|
|
||||||
TransformAction(Promise<T> src, Promise<V> dest, Function<? super T, V> func) {
|
private TransformAction(Promise<T> src, Promise<V> dest, Function<? super T, V> func) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.func = func;
|
this.func = func;
|
||||||
|
@ -33,15 +33,15 @@ import java.util.concurrent.TimeoutException;
|
|||||||
*/
|
*/
|
||||||
class PromiseSupport<T> implements Future<T> {
|
class PromiseSupport<T> implements Future<T> {
|
||||||
|
|
||||||
static final int RUNNING = 1;
|
private static final int RUNNING = 1;
|
||||||
static final int FAILED = 2;
|
private static final int FAILED = 2;
|
||||||
static final int COMPLETED = 3;
|
private static final int COMPLETED = 3;
|
||||||
|
|
||||||
final Object lock;
|
private final Object lock;
|
||||||
|
|
||||||
volatile int state = RUNNING;
|
private volatile int state = RUNNING;
|
||||||
T value;
|
private T value;
|
||||||
Exception exception;
|
private Exception exception;
|
||||||
|
|
||||||
PromiseSupport() {
|
PromiseSupport() {
|
||||||
this.lock = new Object();
|
this.lock = new Object();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user