diff --git a/promise/etc/promise.png b/promise/etc/promise.png new file mode 100644 index 000000000..1a0f67108 Binary files /dev/null and b/promise/etc/promise.png differ diff --git a/promise/etc/promise.ucls b/promise/etc/promise.ucls new file mode 100644 index 000000000..fe3c6c2e0 --- /dev/null +++ b/promise/etc/promise.ucls @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/promise/src/main/java/com/iluwatar/promise/App.java b/promise/src/main/java/com/iluwatar/promise/App.java index 3390f2a23..6ce7de994 100644 --- a/promise/src/main/java/com/iluwatar/promise/App.java +++ b/promise/src/main/java/com/iluwatar/promise/App.java @@ -1,5 +1,28 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.promise; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -7,14 +30,31 @@ import java.util.concurrent.Executors; /** * - * Application that uses promise pattern. + *

The Promise object is used for asynchronous computations. A Promise represents an operation that + * hasn't completed yet, but is expected in the future. + * + *

A Promise represents a proxy for a value not necessarily known when the promise is created. It + * allows you to associate dependent promises to an asynchronous action's eventual success value or + * failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final + * value, the asynchronous method returns a promise of having a value at some point in the future. + * + *

Promises provide a few advantages over callback objects: + *

+ * + * @see CompletableFuture */ public class App { + private App() { + } + /** * Program entry point * @param args arguments - * @throws InterruptedException if main thread is interruped. + * @throws InterruptedException if main thread is interrupted. * @throws ExecutionException if an execution error occurs. */ public static void main(String[] args) throws InterruptedException, ExecutionException { diff --git a/promise/src/main/java/com/iluwatar/promise/Promise.java b/promise/src/main/java/com/iluwatar/promise/Promise.java index 03977c541..fe7dc6f9f 100644 --- a/promise/src/main/java/com/iluwatar/promise/Promise.java +++ b/promise/src/main/java/com/iluwatar/promise/Promise.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.promise; import java.util.concurrent.Callable; @@ -8,6 +30,7 @@ import java.util.function.Function; /** * Implements the promise pattern. + * * @param type of result. */ public class Promise extends PromiseSupport { @@ -41,7 +64,7 @@ public class Promise extends PromiseSupport { postFulfillment(); } - void postFulfillment() { + private void postFulfillment() { if (fulfillmentAction == null) { return; } diff --git a/promise/src/main/java/com/iluwatar/promise/PromiseSupport.java b/promise/src/main/java/com/iluwatar/promise/PromiseSupport.java new file mode 100644 index 000000000..dde2ca452 --- /dev/null +++ b/promise/src/main/java/com/iluwatar/promise/PromiseSupport.java @@ -0,0 +1,119 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.promise; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * A really simplified implementation of future that allows completing it successfully with a value + * or exceptionally with an exception. + */ +class PromiseSupport implements Future { + + static final int RUNNING = 1; + static final int FAILED = 2; + static final int COMPLETED = 3; + + final Object lock; + + volatile int state = RUNNING; + T value; + Exception exception; + + PromiseSupport() { + this.lock = new Object(); + } + + void fulfill(T value) { + this.value = value; + this.state = COMPLETED; + synchronized (lock) { + lock.notifyAll(); + } + } + + void fulfillExceptionally(Exception exception) { + this.exception = exception; + this.state = FAILED; + synchronized (lock) { + lock.notifyAll(); + } + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return state > RUNNING; + } + + @Override + public T get() throws InterruptedException, ExecutionException { + if (state == COMPLETED) { + return value; + } else if (state == FAILED) { + throw new ExecutionException(exception); + } else { + synchronized (lock) { + lock.wait(); + if (state == COMPLETED) { + return value; + } else { + throw new ExecutionException(exception); + } + } + } + } + + @Override + public T get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + if (state == COMPLETED) { + return value; + } else if (state == FAILED) { + throw new ExecutionException(exception); + } else { + synchronized (lock) { + lock.wait(unit.toMillis(timeout)); + if (state == COMPLETED) { + return value; + } else if (state == FAILED) { + throw new ExecutionException(exception); + } else { + throw new TimeoutException(); + } + } + } + } +} \ No newline at end of file diff --git a/promise/src/test/java/com/iluwatar/promise/AppTest.java b/promise/src/test/java/com/iluwatar/promise/AppTest.java index b2628127c..1d1cb061d 100644 --- a/promise/src/test/java/com/iluwatar/promise/AppTest.java +++ b/promise/src/test/java/com/iluwatar/promise/AppTest.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.promise; import java.util.concurrent.ExecutionException; diff --git a/promise/src/test/java/com/iluwatar/promise/PromiseTest.java b/promise/src/test/java/com/iluwatar/promise/PromiseTest.java index 842558589..de0ecb6d7 100644 --- a/promise/src/test/java/com/iluwatar/promise/PromiseTest.java +++ b/promise/src/test/java/com/iluwatar/promise/PromiseTest.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.promise; import static org.junit.Assert.assertEquals;