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."); } }