From 6e90036f081323181de7b6b6a6b76feb635b6d4a Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 15 Nov 2018 18:25:31 +0200 Subject: [PATCH] Add project files --- build.xml | 73 + nbproject/build-impl.xml | 1419 +++++++++++++++++ nbproject/genfiles.properties | 8 + nbproject/private/config.properties | 0 nbproject/private/private.properties | 6 + nbproject/private/private.xml | 8 + nbproject/project.properties | 78 + nbproject/project.xml | 15 + .../countdownlatch/CountDownLatchDemo.java | 37 + .../countdownlatch/WaitToComplete.java | 66 + .../cyclicbarrier/CyclicBarrierDemo.java | 59 + src/concurrency/exchanger/ExchangerDemo.java | 67 + src/concurrency/executors/CallableDemo.java | 84 + .../executors/PiCalculatorDemo.java | 50 + .../executors/SimpleExecutorDemo.java | 50 + src/concurrency/phaser/PhaserDemo.java | 68 + src/concurrency/phaser/PhaserDemo2.java | 77 + .../semaphore/DecrementThread.java | 39 + .../semaphore/IncrementThread.java | 39 + .../semaphore/ProducerConsumerDemo.java | 82 + src/concurrency/semaphore/SemaphoreDemo.java | 21 + 21 files changed, 2346 insertions(+) create mode 100644 build.xml create mode 100644 nbproject/build-impl.xml create mode 100644 nbproject/genfiles.properties create mode 100644 nbproject/private/config.properties create mode 100644 nbproject/private/private.properties create mode 100644 nbproject/private/private.xml create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml create mode 100644 src/concurrency/countdownlatch/CountDownLatchDemo.java create mode 100644 src/concurrency/countdownlatch/WaitToComplete.java create mode 100644 src/concurrency/cyclicbarrier/CyclicBarrierDemo.java create mode 100644 src/concurrency/exchanger/ExchangerDemo.java create mode 100644 src/concurrency/executors/CallableDemo.java create mode 100644 src/concurrency/executors/PiCalculatorDemo.java create mode 100644 src/concurrency/executors/SimpleExecutorDemo.java create mode 100644 src/concurrency/phaser/PhaserDemo.java create mode 100644 src/concurrency/phaser/PhaserDemo2.java create mode 100644 src/concurrency/semaphore/DecrementThread.java create mode 100644 src/concurrency/semaphore/IncrementThread.java create mode 100644 src/concurrency/semaphore/ProducerConsumerDemo.java create mode 100644 src/concurrency/semaphore/SemaphoreDemo.java diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..0284028 --- /dev/null +++ b/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project Concurrency. + + + diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..2225f72 --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..48eb0f1 --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=6babcc3e +build.xml.script.CRC32=7a9b2ac7 +build.xml.stylesheet.CRC32=8064a381@1.78.0.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=6babcc3e +nbproject/build-impl.xml.script.CRC32=2551e2ff +nbproject/build-impl.xml.stylesheet.CRC32=2b19b096@1.80.0.48 diff --git a/nbproject/private/config.properties b/nbproject/private/config.properties new file mode 100644 index 0000000..e69de29 diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 0000000..fbbfe24 --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,6 @@ +compile.on.save=true +do.depend=false +do.jar=true +javac.debug=true +javadoc.preview=true +user.properties.file=C:\\Users\\aNNiMON\\AppData\\Roaming\\NetBeans\\dev\\build.properties diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..05578e0 --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..f830ef5 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,78 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Concurrency +application.vendor=aNNiMON +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Concurrency.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=true +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit_4.classpath}:\ + ${libs.hamcrest.classpath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=concurrency.semaphore.SemaphoreDemo +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..3a22268 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + Concurrency + + + + + + + + + diff --git a/src/concurrency/countdownlatch/CountDownLatchDemo.java b/src/concurrency/countdownlatch/CountDownLatchDemo.java new file mode 100644 index 0000000..57a283d --- /dev/null +++ b/src/concurrency/countdownlatch/CountDownLatchDemo.java @@ -0,0 +1,37 @@ +package concurrency.countdownlatch; + +import java.util.concurrent.CountDownLatch; + +// An example of CountDownLatch. +public final class CountDownLatchDemo { + + public static void main(String args[]) { + CountDownLatch cdl = new CountDownLatch(5); + System.out.println("Starting"); + new MyThread(cdl); + try { + cdl.await(); + } catch (InterruptedException exc) { + System.out.println(exc); + } + System.out.println("Done"); + } + + static class MyThread implements Runnable { + + CountDownLatch latch; + + MyThread(CountDownLatch c) { + latch = c; + new Thread(this).start(); + } + + @Override + public void run() { + for (int i = 0; i < 5; i++) { + System.out.println(i); + latch.countDown(); // decrement count + } + } + } +} diff --git a/src/concurrency/countdownlatch/WaitToComplete.java b/src/concurrency/countdownlatch/WaitToComplete.java new file mode 100644 index 0000000..f4b74d3 --- /dev/null +++ b/src/concurrency/countdownlatch/WaitToComplete.java @@ -0,0 +1,66 @@ +package concurrency.countdownlatch; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * + * @author aNNiMON + */ +public final class WaitToComplete { + + public static void main(String[] args) throws InterruptedException { +// runInMainThread(); + runInExecutor(); + } + + public static void runInMainThread() throws InterruptedException { +// final Executor executor = Runnable::run; + final Executor executor = new Executor() { + @Override + public void execute(final Runnable command) { + command.run(); + } + }; + final CountDownLatch latch = new CountDownLatch(2); + executor.execute(new FiniteThreadNamePrinterLatch(latch)); + executor.execute(new FiniteThreadNamePrinterLatch(latch)); + final boolean status = latch.await(5, TimeUnit.SECONDS); + System.out.println(status ? "Tasks successfully completed" : "Tasks does not complete, but that's all"); + } + + public static void runInExecutor() throws InterruptedException { + final ExecutorService executor = Executors.newCachedThreadPool(); + final CountDownLatch latch = new CountDownLatch(2); + executor.execute(new FiniteThreadNamePrinterLatch(latch)); + executor.execute(new FiniteThreadNamePrinterLatch(latch)); + final boolean status = latch.await(5, TimeUnit.SECONDS); + System.out.println(status ? "Tasks successfully completed" : "Tasks does not complete, but that's all"); + executor.shutdown(); + } + + private static class FiniteThreadNamePrinterLatch implements Runnable { + + final CountDownLatch latch; + + private FiniteThreadNamePrinterLatch(final CountDownLatch latch) { + this.latch = latch; + } + + @Override + public void run() { + for (int i = 0; i < 25; i++) { + System.out.println("Run from thread: " + Thread.currentThread().getName()); + try { + Thread.sleep(400); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + latch.countDown(); + } + } +} diff --git a/src/concurrency/cyclicbarrier/CyclicBarrierDemo.java b/src/concurrency/cyclicbarrier/CyclicBarrierDemo.java new file mode 100644 index 0000000..acdbe53 --- /dev/null +++ b/src/concurrency/cyclicbarrier/CyclicBarrierDemo.java @@ -0,0 +1,59 @@ +package concurrency.cyclicbarrier; + +// An example of CyclicBarrier. + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public final class CyclicBarrierDemo { + + public static void main(String args[]) { +// CyclicBarrier cb = new CyclicBarrier(3, new BarAction()); + CyclicBarrier cb = new CyclicBarrier(3, () -> System.out.println("Barrier Reached!")); + System.out.println("Starting"); + new MyThread(cb, "A"); + new MyThread(cb, "B"); + new MyThread(cb, "C"); + // ++ + new MyThread(cb, "X"); + new MyThread(cb, "Y"); + new MyThread(cb, "Z"); + // ++ +// for (char ch = 'A'; ch <= 'Z'; ch++) { +// new MyThread(cb, String.valueOf(ch)); +// } + } + + static class MyThread implements Runnable { + CyclicBarrier cbar; + String name; + + MyThread(CyclicBarrier c, String n) { + cbar = c; + name = n; + new Thread(this).start(); + } + + @Override + public void run() { + System.out.println(name); +// for (int i = 0; i < 5; i++) { +// System.out.println(name + " " + i); +// } + try { + cbar.await(); + } catch (BrokenBarrierException | InterruptedException exc) { + System.out.println(exc); + } + } + } + + // An object of this class is called when the + // CyclicBarrier ends. + static class BarAction implements Runnable { + @Override + public void run() { + System.out.println("Barrier Reached!"); + } + } +} diff --git a/src/concurrency/exchanger/ExchangerDemo.java b/src/concurrency/exchanger/ExchangerDemo.java new file mode 100644 index 0000000..5ee12e1 --- /dev/null +++ b/src/concurrency/exchanger/ExchangerDemo.java @@ -0,0 +1,67 @@ +package concurrency.exchanger; + +import java.util.concurrent.Exchanger; + +// An example of Exchanger. +public final class ExchangerDemo { + + public static void main(String args[]) { + Exchanger exgr = new Exchanger<>(); + new UseString(exgr); + new MakeString(exgr); + } + + // A Thread that constructs a string. + static class MakeString implements Runnable { + Exchanger ex; + String str; + + MakeString(Exchanger c) { + ex = c; + str = new String(); + new Thread(this).start(); + } + + @Override + public void run() { + char ch = 'A'; + for (int i = 0; i < 3; i++) { // !!! 3 + // Fill Buffer + for (int j = 0; j < 5; j++) { + str += ch++; + } + try { + // Exchange a full buffer for an empty one. + str = ex.exchange(str); + } catch (InterruptedException exc) { + System.out.println(exc); + } + } + } + } + + // A Thread that uses a string. + static class UseString implements Runnable { + Exchanger ex; + String str; + + UseString(Exchanger c) { + ex = c; + new Thread(this).start(); + } + + @Override + public void run() { + for (int i = 0; i < 3; i++) { // !!! 3 + try { + // Exchange an empty buffer for a full one. + str = ex.exchange(new String()); + System.out.println("Got: " + str); + } catch (InterruptedException exc) { + System.out.println(exc); + } + } + } + } + +} diff --git a/src/concurrency/executors/CallableDemo.java b/src/concurrency/executors/CallableDemo.java new file mode 100644 index 0000000..664ded9 --- /dev/null +++ b/src/concurrency/executors/CallableDemo.java @@ -0,0 +1,84 @@ +package concurrency.executors; + +import java.util.concurrent.*; + +// An example that uses a Callable. +public final class CallableDemo { + + public static void main(String args[]) { + ExecutorService es = Executors.newFixedThreadPool(3); + Future f; + Future f2; + Future f3; + System.out.println("Starting"); + f = es.submit(new Sum(10)); + f2 = es.submit(new Hypot(3, 4)); + f3 = es.submit(new Factorial(15)); +// try { +// System.out.println(f.get()); +// System.out.println(f2.get()); +// System.out.println(f3.get()); +// } catch (InterruptedException | ExecutionException exc) { +// System.out.println(exc); +// } + try { + System.out.println(f.get(10, TimeUnit.MILLISECONDS)); + System.out.println(f2.get(10, TimeUnit.MILLISECONDS)); + System.out.println(f3.get(10, TimeUnit.MILLISECONDS)); + } catch (InterruptedException | ExecutionException | TimeoutException exc) { + System.out.println(exc); + } + es.shutdown(); + System.out.println("Done"); + } + +// Following are three computational threads. + + static class Sum implements Callable { + int stop; + + Sum(int v) { + stop = v; + } + + @Override + public Integer call() { + int sum = 0; + for (int i = 1; i <= stop; i++) { + sum += i; + } + return sum; + } + } + + static class Hypot implements Callable { + double side1, side2; + + Hypot(double s1, double s2) { + side1 = s1; + side2 = s2; + } + + @Override + public Double call() { + return Math.sqrt((side1 * side1) + (side2 * side2)); + } + } + + static class Factorial implements Callable { + int stop; + + Factorial(int v) { + stop = v; + } + + @Override + public Long call() { + long fact = 1; + for (int i = 2; i <= stop; i++) { + fact *= i; + } + return fact; + } + } +} diff --git a/src/concurrency/executors/PiCalculatorDemo.java b/src/concurrency/executors/PiCalculatorDemo.java new file mode 100644 index 0000000..ddb3179 --- /dev/null +++ b/src/concurrency/executors/PiCalculatorDemo.java @@ -0,0 +1,50 @@ +package concurrency.executors; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * @author aNNiMON + */ +public final class PiCalculatorDemo { + + public static void main(String[] args) { + final ExecutorService executorService = Executors.newCachedThreadPool(); + final long startTime = System.currentTimeMillis(); + final Future future = executorService.submit(new PiCalculator()); + try { + final double pi = future.get(10, TimeUnit.SECONDS); + final long stopTime = System.currentTimeMillis(); + System.out.printf("Calculated Pi in %d milliseconds: %10.9f%n", stopTime - startTime, pi); + } catch (InterruptedException | ExecutionException | TimeoutException ex) { + ex.printStackTrace(); + executorService.submit(() -> System.exit(0)); + } finally { + executorService.shutdown(); + } + } + + private static class PiCalculator implements Callable { + + @Override + public Double call() throws Exception { + double currVal = 1.0; + double nextVal = 0.0; + double denominator = 1.0; + for (int i = 0; Math.abs(nextVal - currVal) > 0.000000001d; denominator += 2.0, i++) { + currVal = nextVal; + if (i % 2 == 1) { + nextVal = currVal - (1 / denominator); + } else { + nextVal = currVal + (1 / denominator); + } + } + return currVal * 4; + } + } +} diff --git a/src/concurrency/executors/SimpleExecutorDemo.java b/src/concurrency/executors/SimpleExecutorDemo.java new file mode 100644 index 0000000..aca214b --- /dev/null +++ b/src/concurrency/executors/SimpleExecutorDemo.java @@ -0,0 +1,50 @@ +package concurrency.executors; + +import java.util.concurrent.*; + +// A simple example that uses an Executor. +public final class SimpleExecutorDemo { + + public static void main(String args[]) { + CountDownLatch cdl = new CountDownLatch(5); + CountDownLatch cdl2 = new CountDownLatch(5); + CountDownLatch cdl3 = new CountDownLatch(5); + CountDownLatch cdl4 = new CountDownLatch(5); + ExecutorService es = Executors.newFixedThreadPool(2); + System.out.println("Starting"); + // Start the threads. + es.execute(new MyThread(cdl, "A")); + es.execute(new MyThread(cdl2, "B")); + es.execute(new MyThread(cdl3, "C")); + es.execute(new MyThread(cdl4, "D")); + try { + cdl.await(); + cdl2.await(); + cdl3.await(); + cdl4.await(); + } catch (InterruptedException exc) { + System.out.println(exc); + } + es.shutdown(); + System.out.println("Done"); + } + + static class MyThread implements Runnable { + String name; + CountDownLatch latch; + + MyThread(CountDownLatch c, String n) { + latch = c; + name = n; + new Thread(this); + } + + @Override + public void run() { + for (int i = 0; i < 5; i++) { + System.out.println(name + ": " + i); + latch.countDown(); + } + } + } +} diff --git a/src/concurrency/phaser/PhaserDemo.java b/src/concurrency/phaser/PhaserDemo.java new file mode 100644 index 0000000..955a9ed --- /dev/null +++ b/src/concurrency/phaser/PhaserDemo.java @@ -0,0 +1,68 @@ +package concurrency.phaser; + +// An example of Phaser. +import java.util.concurrent.*; + +public final class PhaserDemo { + + public static void main(String args[]) { + Phaser phsr = new Phaser(1); + int curPhase; + System.out.println("Starting"); + new MyThread(phsr, "A"); + new MyThread(phsr, "B"); + new MyThread(phsr, "C"); + // Wait for all threads to complete phase one. + curPhase = phsr.getPhase(); + phsr.arriveAndAwaitAdvance(); + System.out.println("Phase " + curPhase + " Complete"); + // Wait for all threads to complete phase two. + curPhase = phsr.getPhase(); + phsr.arriveAndAwaitAdvance(); + System.out.println("Phase " + curPhase + " Complete"); + curPhase = phsr.getPhase(); + phsr.arriveAndAwaitAdvance(); + System.out.println("Phase " + curPhase + " Complete"); + // Deregister the main thread. + phsr.arriveAndDeregister(); + if (phsr.isTerminated()) + System.out.println("The Phaser is terminated"); + } +} + +// A thread of execution that uses a Phaser. +class MyThread implements Runnable { + Phaser phsr; + String name; + + MyThread(Phaser p, String n) { + phsr = p; + name = n; + phsr.register(); // !!! + new Thread(this).start(); + } + + @Override + public void run() { + System.out.println("Thread " + name + " Beginning Phase One"); + phsr.arriveAndAwaitAdvance(); // Signal arrival. + // Pause a bit to prevent jumbled output. This is for illustration + // only. It is not required for the proper operation of the phaser. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + System.out.println(e); + } + System.out.println("Thread " + name + " Beginning Phase Two"); + phsr.arriveAndAwaitAdvance(); // Signal arrival. + // Pause a bit to prevent jumbled output. This is for illustration + // only. It is not required for the proper operation of the phaser. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + System.out.println(e); + } + System.out.println("Thread " + name + " Beginning Phase Three"); + phsr.arriveAndDeregister(); // Signal arrival and deregister. + } +} diff --git a/src/concurrency/phaser/PhaserDemo2.java b/src/concurrency/phaser/PhaserDemo2.java new file mode 100644 index 0000000..4e3dffd --- /dev/null +++ b/src/concurrency/phaser/PhaserDemo2.java @@ -0,0 +1,77 @@ +package concurrency.phaser; + +import java.util.concurrent.Phaser; + +/** + * + * @author aNNiMON + */ +public final class PhaserDemo2 { + + public static void main(String args[]) { + MyPhaser phsr = new MyPhaser(1, 4); + System.out.println("Starting\n"); + new MyThread2(phsr, "A"); + new MyThread2(phsr, "B"); + new MyThread2(phsr, "C"); +// Wait for the specified number of phases to complete. + while (!phsr.isTerminated()) { + phsr.arriveAndAwaitAdvance(); + } + System.out.println("The Phaser is terminated"); + } +} + +// A thread of execution that uses a Phaser. +class MyThread2 implements Runnable { + + Phaser phsr; + String name; + + MyThread2(Phaser p, String n) { + phsr = p; + name = n; + phsr.register(); + new Thread(this).start(); + } + + @Override + public void run() { + while (!phsr.isTerminated()) { + System.out.println("Thread " + name + " Beginning Phase " + phsr.getPhase()); + phsr.arriveAndAwaitAdvance(); + // Pause a bit to prevent jumbled output. This is for illustration + // only. It is not required for the proper operation of the phaser. + try { + Thread.sleep(10); + } catch (InterruptedException e) { + System.out.println(e); + } + } + } +} + +// Extend MyPhaser to allow only a specific number of phases +// to be executed. +class MyPhaser extends Phaser { + int numPhases; + + MyPhaser(int parties, int phaseCount) { + super(parties); + numPhases = phaseCount - 1; + } + + // Override onAdvance() to execute the specified + // number of phases. + @Override + protected boolean onAdvance(int p, int regParties) { + // This println() statement is for illustration only. + // Normally, onAdvance() will not display output. + System.out.println("Phase " + p + " completed.\n"); + // If all phases have completed, return true + if (p == numPhases || regParties == 0) + return true; + // Otherwise, return false. + return false; + } +} diff --git a/src/concurrency/semaphore/DecrementThread.java b/src/concurrency/semaphore/DecrementThread.java new file mode 100644 index 0000000..4bf9f7b --- /dev/null +++ b/src/concurrency/semaphore/DecrementThread.java @@ -0,0 +1,39 @@ +package concurrency.semaphore; + +import java.util.concurrent.Semaphore; + +// A thread of execution that decrements count. +public final class DecrementThread implements Runnable { + + String name; + Semaphore sem; + + DecrementThread(Semaphore s, String n) { + sem = s; + name = n; + new Thread(this).start(); + } + + @Override + public void run() { + System.out.println("Starting " + name); + try { + // First, get a permit. + System.out.println(name + " is waiting for a permit."); + sem.acquire(); + System.out.println(name + " gets a permit."); + // Now, access shared resource. + for (int i = 0; i < 5; i++) { + Shared.count--; + System.out.println(name + ": " + Shared.count); + // Now, allow a context switch -- if possible. + Thread.sleep(10); + } + } catch (InterruptedException exc) { + System.out.println(exc); + } + // Release the permit. + System.out.println(name + " releases the permit."); + sem.release(); + } +} \ No newline at end of file diff --git a/src/concurrency/semaphore/IncrementThread.java b/src/concurrency/semaphore/IncrementThread.java new file mode 100644 index 0000000..4277c48 --- /dev/null +++ b/src/concurrency/semaphore/IncrementThread.java @@ -0,0 +1,39 @@ +package concurrency.semaphore; + +import java.util.concurrent.Semaphore; + +// A thread of execution that increments count. +public final class IncrementThread implements Runnable { + + String name; + Semaphore sem; + + IncrementThread(Semaphore s, String n) { + sem = s; + name = n; + new Thread(this).start(); + } + + @Override + public void run() { + System.out.println("Starting " + name); + try { + // First, get a permit. + System.out.println(name + " is waiting for a permit."); + sem.acquire(); + System.out.println(name + " gets a permit."); + // Now, access shared resource. + for (int i = 0; i < 5; i++) { + Shared.count++; + System.out.println(name + ": " + Shared.count); + // Now, allow a context switch -- if possible. + Thread.sleep(10); + } + } catch (InterruptedException exc) { + System.out.println(exc); + } + // Release the permit. + System.out.println(name + " releases the permit."); + sem.release(); + } +} diff --git a/src/concurrency/semaphore/ProducerConsumerDemo.java b/src/concurrency/semaphore/ProducerConsumerDemo.java new file mode 100644 index 0000000..e9bc2f0 --- /dev/null +++ b/src/concurrency/semaphore/ProducerConsumerDemo.java @@ -0,0 +1,82 @@ +package concurrency.semaphore; + +import java.util.concurrent.Semaphore; + +// An implementation of a producer and consumer +// that use semaphores to control synchronization. +public final class ProducerConsumerDemo { + + public static void main(String args[]) { + new ProducerConsumerDemo(); + } + + public ProducerConsumerDemo() { + Q q = new Q(); + new Consumer(q); + new Producer(q); + } + + static class Q { + int n; + // Start with consumer semaphore unavailable. + static Semaphore semCon = new Semaphore(0); + static Semaphore semProd = new Semaphore(1); + + void get() { + try { +// System.out.println(Thread.currentThread().getName() + " is waiting for a permit in get"); + semCon.acquire(); +// System.out.println(Thread.currentThread().getName() + " gets a permit in get."); + } catch (InterruptedException e) { + System.out.println("InterruptedException caught"); + } + System.out.println("Got: " + n); + semProd.release(); + } + + void put(int n) { + try { +// System.out.println(Thread.currentThread().getName() + " is waiting for a permit in put"); + semProd.acquire(); +// System.out.println(Thread.currentThread().getName() + " gets a permit in put."); + } catch (InterruptedException e) { + System.out.println("InterruptedException caught"); + } + this.n = n; + System.out.println("Put: " + n); + semCon.release(); + } + } + + class Producer implements Runnable { + Q q; + + Producer(Q q) { + this.q = q; + new Thread(this, "Producer").start(); + } + + @Override + public void run() { + for (int i = 0; i < 20; i++) { + q.put(i); + } + } + } + + class Consumer implements Runnable { + Q q; + + Consumer(Q q) { + this.q = q; + new Thread(this, "Consumer").start(); + } + + @Override + public void run() { + for (int i = 0; i < 20; i++) { + q.get(); + } + } + } +} diff --git a/src/concurrency/semaphore/SemaphoreDemo.java b/src/concurrency/semaphore/SemaphoreDemo.java new file mode 100644 index 0000000..2fefdc2 --- /dev/null +++ b/src/concurrency/semaphore/SemaphoreDemo.java @@ -0,0 +1,21 @@ +package concurrency.semaphore; + +import java.util.concurrent.Semaphore; + +/** + * + * @author aNNiMON + */ +public final class SemaphoreDemo { + + public static void main(String[] args) { + Semaphore sem = new Semaphore(1); + new IncrementThread(sem, "A"); + new DecrementThread(sem, "B"); + } +} +// A shared resource. + +class Shared { + static int count = 0; +}