diff --git a/JavaMultiThreadingCodes/build.xml b/JavaMultiThreadingCodes/build.xml
deleted file mode 100644
index 5400628..0000000
--- a/JavaMultiThreadingCodes/build.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Builds, tests, and runs the project JavaMultiThreadingCodes.
-
-
-
diff --git a/JavaMultiThreadingCodes/manifest.mf b/JavaMultiThreadingCodes/manifest.mf
deleted file mode 100644
index 1574df4..0000000
--- a/JavaMultiThreadingCodes/manifest.mf
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-X-COMMENT: Main-Class will be added automatically by build
-
diff --git a/JavaMultiThreadingCodes/nbproject/build-impl.xml b/JavaMultiThreadingCodes/nbproject/build-impl.xml
deleted file mode 100644
index f882b0b..0000000
--- a/JavaMultiThreadingCodes/nbproject/build-impl.xml
+++ /dev/null
@@ -1,1413 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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/JavaMultiThreadingCodes/nbproject/genfiles.properties b/JavaMultiThreadingCodes/nbproject/genfiles.properties
deleted file mode 100644
index 9cd2362..0000000
--- a/JavaMultiThreadingCodes/nbproject/genfiles.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-build.xml.data.CRC32=4d3d93c3
-build.xml.script.CRC32=a6a26692
-build.xml.stylesheet.CRC32=8064a381@1.74.2.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=4d3d93c3
-nbproject/build-impl.xml.script.CRC32=fa6ba560
-nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.2.48
diff --git a/JavaMultiThreadingCodes/nbproject/project.properties b/JavaMultiThreadingCodes/nbproject/project.properties
deleted file mode 100644
index bb953fd..0000000
--- a/JavaMultiThreadingCodes/nbproject/project.properties
+++ /dev/null
@@ -1,73 +0,0 @@
-annotation.processing.enabled=true
-annotation.processing.enabled.in.editor=false
-annotation.processing.processor.options=
-annotation.processing.processors.list=
-annotation.processing.run.all.processors=true
-annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
-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}/JavaMultiThreadingCodes.jar
-dist.javadoc.dir=${dist.dir}/javadoc
-excludes=
-includes=**
-jar.compress=false
-javac.classpath=
-# Space-separated list of extra javac options
-javac.compilerargs=
-javac.deprecation=false
-javac.processorpath=\
- ${javac.classpath}
-javac.source=1.7
-javac.target=1.7
-javac.test.classpath=\
- ${javac.classpath}:\
- ${build.classes.dir}
-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=javaapplication7.JavaApplication7
-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/JavaMultiThreadingCodes/nbproject/project.xml b/JavaMultiThreadingCodes/nbproject/project.xml
deleted file mode 100644
index 10729ea..0000000
--- a/JavaMultiThreadingCodes/nbproject/project.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- org.netbeans.modules.java.j2seproject
-
-
- JavaMultiThreadingCodes
-
-
-
-
-
-
-
-
-
diff --git a/JavaMultiThreadingCodes/src/CallableAndFuture_13/App.java b/JavaMultiThreadingCodes/src/CallableAndFuture_13/App.java
index 33624a8..2706d4b 100644
--- a/JavaMultiThreadingCodes/src/CallableAndFuture_13/App.java
+++ b/JavaMultiThreadingCodes/src/CallableAndFuture_13/App.java
@@ -10,41 +10,30 @@
* your threads to throw exceptions. Plus, Future allows you to control your
* threads, checking to see if they’re running or not, waiting for results and
* even interrupting them or de-scheduling them.
- *
+
* {@link java.lang.Runnable}
* is the default abstraction for creating a task in Java. It has a single
* method {@link Runnable#run()}
* that accepts no arguments and returns no value, nor it can throw
* any checked exception. To overcome these limitations, Java 5 introduced a new
* task abstraction through {@link java.util.concurrent.Callable} interface.
- *
- * Codes with minor comments are from
- *
- * http://www.caveofprogramming.com/youtube/
- *
- *
- * also freely available at
- *
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- *
- * @author Z.B. Celik
*/
public class App {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newCachedThreadPool();
- //anonymous call of Callable
- Future future = executor.submit(new Callable() {
-
+ // Callable instead of Runnable, can return result instead of void
+ // if don't want to use return value now, but may use it in the future:
+ // Future> future = executor.submit(new Callable() {
+ Future future = executor.submit(new Callable() {
+
@Override
- //return value is Integer
- public Integer call() throws TimeoutException {
+ public Integer call() throws TimeoutException {
Random random = new Random();
int duration = random.nextInt(4000);
if (duration > 2000) {
- throw new TimeoutException ("Sleeping for too long.");
+ throw new TimeoutException ("Sleeping for too long.");
}
System.out.println("Starting ...");
@@ -57,15 +46,14 @@ public Integer call() throws TimeoutException {
});
executor.shutdown();
-// executor.awaitTermination(1, TimeUnit.DAYS);
- try {
- //get returned value from call()
- System.out.println("Result is: " + future.get());
-
+ // can wait for threads to finish, if not, when use future.get() it will block till threads finish
+ // executor.awaitTermination(1, TimeUnit.DAYS);
+ try {
+ System.out.println("Result is: " + future.get()); //get returned value from call()
} catch (InterruptedException ignored) {
} catch (ExecutionException e) {
TimeoutException ex = (TimeoutException) e.getCause();
- System.out.println(ex.getMessage());
+ System.out.println(ex.getMessage()); // Will print "sleeping for too long"
}
}
diff --git a/JavaMultiThreadingCodes/src/CountDownLatch_6/App.java b/JavaMultiThreadingCodes/src/CountDownLatch_6/App.java
index 20164d7..cdce4e7 100644
--- a/JavaMultiThreadingCodes/src/CountDownLatch_6/App.java
+++ b/JavaMultiThreadingCodes/src/CountDownLatch_6/App.java
@@ -5,36 +5,16 @@
import java.util.concurrent.Executors;
/**
- * {@link java.util.concurrent.CountDownLatch} Java class to synchronize your threads’ activities.
- *
- * Source:
- * http://stackoverflow.com/questions/17827022/what-is-countdown-latch-in-java-multithreading
- *
* Any thread, usually main thread of application, which calls
- * {@link java.util.concurrent.CountDownLatch#await()} will wait until count reaches zero or its interrupted
+ * latch.await() will wait until count reaches zero or interrupted
* by another thread. All other thread are required to do count down by calling
- * {@link java.util.concurrent.CountDownLatch#countDown()} once they are completed or ready.
- *
- * As soon as count reaches zero, Thread awaiting starts running. One of the
- * disadvantage of {@link java.util.concurrent.CountDownLatch} is that it's
- * not reusable once the count reaches to
- * zero you can not use {@link java.util.concurrent.CountDownLatch} any more.
- *
- * Use {@link java.util.concurrent.CountDownLatch} when one thread, like main
- * thread, require to wait for one or more threads to complete, before it can
- * start processing.
- *
- * Classical example of using {@link java.util.concurrent.CountDownLatch} in
- * Java is any server side core Java application which uses services
- * architecture, where multiple services
- * are provided by multiple threads and application can not start processing
+ * CountDownLatch#countDown() once they are completed or ready.
+
+ * As soon as count reaches zero, Thread awaiting starts running.
+
+ * Classical example usage is, when using services architecture, where multiple services
+ * are provided by multiple threads, application can not start processing
* until all services have started successfully.
- *
- * Codes with minor comments are from http://www.caveofprogramming.com/youtube/
- * also freely available at
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- * @author Z.B. Celik
*/
class Processor implements Runnable {
@@ -50,7 +30,7 @@ public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException ignored) {}
- latch.countDown();
+ latch.countDown(); // latch--
}
}
@@ -65,9 +45,7 @@ public static void main(String[] args) {
executor.shutdown();
try {
- // Application’s main thread waits, till other service threads which are
- // as an example responsible for starting framework services have completed started all services.
- latch.await();
+ latch.await(); // waits till CountDownLatch to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
diff --git a/JavaMultiThreadingCodes/src/Deadlock_11/Runner.java b/JavaMultiThreadingCodes/src/Deadlock_11/Runner.java
index 970a867..666b642 100644
--- a/JavaMultiThreadingCodes/src/Deadlock_11/Runner.java
+++ b/JavaMultiThreadingCodes/src/Deadlock_11/Runner.java
@@ -42,11 +42,11 @@ private void acquireLocks(Lock firstLock, Lock secondLock) throws InterruptedExc
* it's unavailable wait for the specified timer to expire
* before giving up
*/
- gotFirstLock = firstLock.tryLock();
+ gotFirstLock = firstLock.tryLock();
gotSecondLock = secondLock.tryLock();
} finally {
if (gotFirstLock && gotSecondLock) return;
- else if (gotFirstLock) firstLock.unlock();
+ else if (gotFirstLock) firstLock.unlock(); // give other threads a chance to get all locks
else if (gotSecondLock) secondLock.unlock();
}
// Locks not acquired
diff --git a/JavaMultiThreadingCodes/src/InterruptingThreads14/App.java b/JavaMultiThreadingCodes/src/InterruptingThreads14/App.java
index a843f1e..2e269d2 100644
--- a/JavaMultiThreadingCodes/src/InterruptingThreads14/App.java
+++ b/JavaMultiThreadingCodes/src/InterruptingThreads14/App.java
@@ -3,66 +3,50 @@
import java.util.concurrent.*;
/**
- * How to interrupt running threads in Java using the built-in thread
- * interruption mechanism.
- *
+ * How to interrupt running threads in Java using the built-in thread interruption mechanism.
* Source:
*
* http://www.javamex.com/tutorials/threads/thread_interruption.shtml
- *
- * Incidentally, it is important NOT to confuse thread interruption with either
- * software interrupts (where the CPU automatically interrupts the current
- * instruction flow in order to call a registered piece of code periodically— as
- * in fact happens to drive the thread scheduler) and hardware interrupts (where
- * the CPU automatically performs a similar task in response to some hardware
- * signal).
- *
- * Codes with minor comments are from
- *
- * http://www.caveofprogramming.com/youtube/
- *
- *
- * also freely available at
- *
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- *
- * @author Z.B. Celik
+
+ * Thread vs software vs hardware interruption:
+ * Software: CPU automatically interrupts the current instruction flow in order to call a registered piece of code periodically
+ * as in fact happens to drive the thread scheduler
+ * Hardware: CPU automatically performs a similar task in response to some hardware signal.
*/
public class App {
public static void main(String[] args) throws InterruptedException {
System.out.println("Starting.");
-
ExecutorService executor = Executors.newCachedThreadPool();
-
+
Future> fu = executor.submit(new Callable() {
-
@Override
public Void call() throws Exception {
-
for (int i = 0; i < 1E8; i++) {
if (Thread.currentThread().isInterrupted()) {
System.out.printf("Interrupted at %d !!!", i);
break;
}
- }
-
+ // instead of using Thread.currentThread().isInterrupted() to detect interrupt,
+ // can also use sleep, which may throw InterruptException:
+ /*try {
+ Thread.sleep(1);
+ } catch (InterruptException e) {
+ System.out.println("Interrupted!");
+ break;
+ }*/
+ }
return null;
}
});
executor.shutdown();
Thread.sleep(500);
-
- /*
- in this example, there are different ways you can interrupt a thread
- execution.
- */
+ // t1.interrupt() won't stop thread, will only set flag that thread is interrupted
//JavaDoc: http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html#cancel-boolean-
-// fu.cancel(true);
+ //fu.cancel(true);
//JavaDoc: http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow--
executor.shutdownNow();
diff --git a/JavaMultiThreadingCodes/src/LowLevelProducerConsumer_9/Processor.java b/JavaMultiThreadingCodes/src/LowLevelProducerConsumer_9/Processor.java
index e061c1d..1f44198 100644
--- a/JavaMultiThreadingCodes/src/LowLevelProducerConsumer_9/Processor.java
+++ b/JavaMultiThreadingCodes/src/LowLevelProducerConsumer_9/Processor.java
@@ -4,31 +4,21 @@
import java.util.Random;
/**
- * Codes with minor comments are from
- *
- * http://www.caveofprogramming.com/youtube/
- *
- *
- * also freely available at
- *
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- *
- * @author Z.B. Celik
+ * Created a low-level version of BlockingQueue.
*/
@SuppressWarnings("InfiniteLoopStatement")
public class Processor {
private LinkedList list = new LinkedList<>();
private final int LIMIT = 10;
- private final Object lock = new Object();
+ private final Object lock = new Object();
public void produce() throws InterruptedException {
int value = 0;
while (true) {
synchronized (lock) {
//whenever the thread is notified starts again from the loop
- while (list.size() == LIMIT) {
+ while (list.size() == LIMIT) { // same effect as [BlockingQueue]
lock.wait();// wait() is also true
}
list.add(value);
@@ -48,7 +38,7 @@ public void consume() throws InterruptedException {
lock.wait();
}
- int value = list.removeFirst();
+ int value = list.removeFirst(); // remove first and then add on last -> queue
System.out.print("Removed value by consumer is: " + value);
System.out.println(" Now list size is: " + list.size());
lock.notify();
diff --git a/JavaMultiThreadingCodes/src/ProducerConsumer_7/App.java b/JavaMultiThreadingCodes/src/ProducerConsumer_7/App.java
index b064da4..fc7a005 100644
--- a/JavaMultiThreadingCodes/src/ProducerConsumer_7/App.java
+++ b/JavaMultiThreadingCodes/src/ProducerConsumer_7/App.java
@@ -1,24 +1,10 @@
package ProducerConsumer_7;
/**
- * Producer-Consumer pattern in Java using the {@link java.util.concurrent
- * .ArrayBlockingQueue} Java class.
- *
+ * Producer-Consumer pattern in Java using the java.util.concurrent.ArrayBlockingQueue
* Producer-Consumer is the situation where one or more threads are producing
* data items and adding them to a shared data store of some kind while one or
* more other threads process those items, removing them from the data store.
- *
- * Codes with minor comments are from
- *
- * http://www.caveofprogramming.com/youtube/
- *
- *
- * also freely available at
- *
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- *
- * @author Z.B. Celik
*/
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
@@ -28,17 +14,8 @@
public class App {
/**
- * Thread safe implementation of {@link java.util.Queue} data structure so
- * you do not need to worry about synchronization.
- * More specifically {@link java.util.concurrent.BlockingQueue}
- * implementations are thread-safe. All queuing methods are atomic in nature
- * and use internal locks or other forms of concurrency control. If
- * BlockingQueue is not used queue is shared data structure either
- * {@code synchronized} or {@code wait() notify()} (see Course 8) should be
- * used.
- * Java 1.5 introduced a new concurrency library {@link java.util.concurrent}
- * which was designed to provide a higher level abstraction over
- * the wait/notify mechanism.
+ * Thread safe implementation of java.util.Queue
+ * java.util.concurrent package are all thread-safe
*/
private static BlockingQueue queue = new ArrayBlockingQueue<>(10);
@@ -61,28 +38,30 @@ public void run() {
});
t1.start();
t2.start();
-// t1.join();
-// t2.join();
+ t1.join();
+ t2.join();
// Pause for 30 seconds and force quitting the app (because we're
// looping infinitely)
Thread.sleep(30000);
System.exit(0);
}
-
+
+ /** producer add integer into queue, and consumer take from queue and send into destination
+ */
private static void producer() throws InterruptedException {
Random random = new Random();
- while (true) {//loop indefinitely
- queue.put(random.nextInt(100));//if queue is full (10) waits
+ while (true) {
+ queue.put(random.nextInt(100)); //if queue is full (10 here) waits
}
}
-
+
private static void consumer() throws InterruptedException {
Random random = new Random();
while (true) {
Thread.sleep(100);
if (random.nextInt(10) == 0) {
- Integer value = queue.take();//if queue is empty waits
+ Integer value = queue.take(); // if queue is empty waits
System.out.println("Taken value: " + value + "; Queue size is: " + queue.size());
}
}
diff --git a/JavaMultiThreadingCodes/src/ReentrantLocks_10/Runner.java b/JavaMultiThreadingCodes/src/ReentrantLocks_10/Runner.java
index b97b4af..a98c741 100644
--- a/JavaMultiThreadingCodes/src/ReentrantLocks_10/Runner.java
+++ b/JavaMultiThreadingCodes/src/ReentrantLocks_10/Runner.java
@@ -51,9 +51,9 @@ public class Runner {
private int count = 0;
private Lock lock = new ReentrantLock();
- private Condition cond = lock.newCondition();
+ private Condition cond = lock.newCondition(); // get Condition object from Lock
- private void increment() {
+ private void increment() {
for (int i = 0; i < 10000; i++) {
count++;
}
@@ -62,22 +62,22 @@ private void increment() {
public void firstThread() throws InterruptedException {
lock.lock();
System.out.println("Waiting ....");
- cond.await();
+ cond.await(); // does same as wait(), this thread will be waiting, until another thread calls signal()
System.out.println("Woken up!");
try {
- increment();
- } finally {
+ increment(); // if increment() thows an exception, will never call unlock()
+ } finally { // so should use finally, garantee unlock always be called
lock.unlock();
}
}
public void secondThread() throws InterruptedException {
Thread.sleep(1000);
- lock.lock();
+ lock.lock();
System.out.println("Press the return key!");
new Scanner(System.in).nextLine();
System.out.println("Got return key!");
- cond.signal();
+ cond.signal(); // notify all waiting threads, another thread wake up.
try {
increment();
} finally {
diff --git a/JavaMultiThreadingCodes/src/Semaphores_12/App.java b/JavaMultiThreadingCodes/src/Semaphores_12/App.java
index 154da74..518e0d0 100644
--- a/JavaMultiThreadingCodes/src/Semaphores_12/App.java
+++ b/JavaMultiThreadingCodes/src/Semaphores_12/App.java
@@ -10,49 +10,30 @@
* can access a resources, but you can also use them to implement deadlock
* recovery systems since a semaphore with one permit is basically a lock that
* can unlock from other threads.
- *
- * Source:
- *
- * http://stackoverflow.com/questions/771347/what-is-mutex-and-semaphore-in-java-what-is-the-main-difference
- *
- *
- * Mutex (or a semaphore initialized to 1; meaning there's only one resource)
+
+ * [Mutex] (or a semaphore initialized to 1; meaning there's only one resource)
* is basically a mutual exclusion; Only one thread can acquire the resource
* at once, and all other threads trying to acquire the resource are blocked
* until the thread owning the resource releases.
- *
- * Semaphore is used to control the number of threads executing. There will be
+
+ * [Semaphore] is used to control the number of threads executing. There will be
* fixed set of resources. The resource count will gets decremented every time
* when a thread owns the same. When the semaphore count reaches 0 then no other
* threads are allowed to acquire the resource. The threads get blocked till
* other threads owning resource releases.
- *
- *
+
* In short, the main difference is how many threads are allowed to acquire the
* resource at once.
* TODO -- go a little more in depth explaining that
* Mutex --its ONE. Semaphore -- its DEFINED_COUNT, ( as many as semaphore
* count)
- *
- *
- * Codes with minor comments are from
- *
- * http://www.caveofprogramming.com/youtube/
- *
- *
- * also freely available at
- *
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- *
- * @author Z.B. Celik
*/
public class App {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newCachedThreadPool();
- for (int i = 0; i < 20; i++) { //200 hundred times will be called
+ for (int i = 0; i < 20; i++) { //create 200 threads
executor.submit(new Runnable() {
public void run() {
Connectionn.getInstance().connect();
diff --git a/JavaMultiThreadingCodes/src/Semaphores_12/Connection.java b/JavaMultiThreadingCodes/src/Semaphores_12/Connection.java
index 88836e2..3e43b77 100644
--- a/JavaMultiThreadingCodes/src/Semaphores_12/Connection.java
+++ b/JavaMultiThreadingCodes/src/Semaphores_12/Connection.java
@@ -1,44 +1,12 @@
package Semaphores_12;
import java.util.concurrent.Semaphore;
-
-/**
- * Semaphores
- *
- * Codes with minor comments are from
- *
- * http://www.caveofprogramming.com/youtube/
- *
- *
- * also freely available at
- *
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- *
- * @author Z.B. Celik
- */
public class Connection {
private static Connection instance = new Connection();
-/*
- limit connections to 10
- true means whichever thread gets first in the waiting pool (queue)
- waiting to acquire a resource, is first to obtain the permit.
-
- Note that I called it a pool!
- The reason is when you say "Queue", you're saying that things are
- scheduled to be FIFO (First In First Out) .. which is not always the case
- here!
- When you initialize the semaphore with Fairness, by setting its second
- argument to true, it will treat the waiting threads like FIFO.
- But,
- it doesn't have to be that way if you don't set on the fairness. the JVM
- may schedule the waiting threads in some other manner that it sees best
- (See the Java specifications for that).
-*/
- private Semaphore sem = new Semaphore(10, true);
- private int connections = 0;
-
+ // [Semaphore] set to true: will guarantee FIFO granting of permits, make sure no server wait too long.
+ private Semaphore sem = new Semaphore(10, true);
+ private int connections = 0; // # of connections in any given time
private Connection() {
}
@@ -48,18 +16,11 @@ public static Connection getInstance() {
public void connect() {
try {
-
- // get permit decrease the sem value, if 0 wait for release
- sem.acquire();
-
- //if doConnect throws and exception is still releases the permit
- //so we use a separate method here to increase the connections count
- doConnect();
-
+ sem.acquire(); // sem value--, if 0 wait for release
+ doConnect(); // might throw exception, so put sem.release in finally block to guarantee release
} catch (InterruptedException ignored) {
- } finally {
- //release permit, increase the sem value and activate waiting thread
- sem.release();
+ } finally {
+ sem.release(); // sem value++, activate waiting thread
}
}
@@ -69,12 +30,11 @@ public void doConnect() {
System.out.println("Current connections (max 10 allowed): " + connections);
}
try {
- //do your job
System.out.println("Working on connections " + Thread.currentThread().getName());
Thread.sleep(2000);
} catch (InterruptedException ignored) {}
//when exit doConnect method decrement number of connections
- synchronized (this) {//atomic
+ synchronized (this) {
connections--;
System.out.println("I'm done " + Thread.currentThread().getName() + " Connection is released , connection count: " + connections);
}
diff --git a/JavaMultiThreadingCodes/src/WaitAndNotify_8/Processor.java b/JavaMultiThreadingCodes/src/WaitAndNotify_8/Processor.java
index 21171c1..5713ef7 100644
--- a/JavaMultiThreadingCodes/src/WaitAndNotify_8/Processor.java
+++ b/JavaMultiThreadingCodes/src/WaitAndNotify_8/Processor.java
@@ -3,37 +3,20 @@
import java.util.Scanner;
/**
- * Some background knowledge
- * Source: http://www.programcreek.com/2009/02/notify-and-wait-example/
- *
- * {@code synchronized} keyword is used for exclusive accessing. To make a
- * method {@code synchronized}, simply add the {@code synchronized} keyword to its
- * declaration.
- * Then no two invocations of synchronized methods on the same object can
+ * Some background knowledge: http://www.programcreek.com/2009/02/notify-and-wait-example/
+ * synchronized keyword is used for exclusive accessing.
+ * no two invocations of synchronized methods on the same object can
* interleave with each other.
- *
* Synchronized statements must specify the object that
* provides the intrinsic lock. When {@code synchronized(this)} is used, you
* have to avoid to synchronizing invocations of other objects' methods.
- *
+
* {@link Object#wait()} tells
* the calling thread to give up the lock and go to sleep (not polling) until
* some other thread enters the same lock and calls {@link Object#notify()}.
- *
+
* {@link Object#notify()} wakes up the first thread that called wait() on
* the same object.
- *
- * Codes with minor comments are from
- *
- * http://www.caveofprogramming.com/youtube/
- *
- *
- * also freely available at
- *
- * https://www.udemy.com/java-multithreading/?couponCode=FREE
- *
- *
- * @author Z.B. Celik
*/
public class Processor {
@@ -48,20 +31,20 @@ public class Processor {
public void produce() throws InterruptedException {
synchronized (this) {
System.out.println("Producer thread running ....");
- wait();//this.wait() is fine.
+ wait(); // more resource efficient than simply use while loop.
System.out.println("Resumed.");
}
}
public void consume() throws InterruptedException {
Scanner scanner = new Scanner(System.in);
- Thread.sleep(2000);
+ Thread.sleep(2000); // make sure produce() before comsume()
synchronized (this) {
System.out.println("Waiting for return key.");
- scanner.nextLine();
+ scanner.nextLine(); // wait till press return key on keyboard
System.out.println("Return key pressed.");
- notify();
- Thread.sleep(5000);
+ notify(); // can only be called in synchronized, call all other threads, if they are waiting, they can wake up
+ Thread.sleep(5000); // this will finish first, before another thread can access
System.out.println("Consumption done.");
}
}