{"id":306,"date":"2021-02-03T22:32:47","date_gmt":"2021-02-03T22:32:47","guid":{"rendered":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/?page_id=306"},"modified":"2021-02-05T16:47:12","modified_gmt":"2021-02-05T16:47:12","slug":"more-on-threads","status":"publish","type":"page","link":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/","title":{"rendered":"More on Threads"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a6d495b9845c\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a6d495b9845c\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Threads_Thread_Groups\" >Threads &amp; Thread Groups<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Default_Thread_Group\" >The Default Thread Group<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Creating_a_Thread_Group\" >Creating a Thread Group<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Thread_Group_Methods\" >Thread Group Methods<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Methods_that_Apply_to_the_ThreadGroup\" >Methods that Apply to the ThreadGroup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Methods_that_Apply_to_all_Threads_in_a_ThreadGroup\" >Methods that Apply to all Threads in a ThreadGroup<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Thread_Group_Tree_Navigation\" >Thread Group Tree Navigation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#An_Example\" >An Example<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Explicit_Locks\" >Explicit Locks<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Lock_Objects\" >Lock Objects<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#ReentrantLock\" >ReentrantLock<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#A_ReentrantLock_Example\" >A ReentrantLock Example<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Finer_Granularity\" >Finer Granularity<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#An_Example-2\" >An Example<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Condition_Objects\" >Condition Objects<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Condition_Interface\" >The Condition Interface<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#await\" >await()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#signal_signalAll\" >signal() &amp; signalAll()<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#An_Example-3\" >An Example<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Explicit_Locks_vs_synchronized\" >Explicit Locks vs. synchronized<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Synchronized_Instance_Methods\" >Synchronized Instance Methods<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Synchronized_Class_Methods\" >Synchronized Class Methods<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_wait_Method\" >The wait() Method<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_notifyAll_Method\" >The notifyAll() Method<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Pros_and_Cons\" >Pros and Cons<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#ReadWrite_Locks\" >Read\/Write Locks<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#ReentrantReadWriteLock\" >ReentrantReadWriteLock<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#An_Example-4\" >An Example<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Atomic_Variables\" >Atomic Variables<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Blocking_Queues\" >Blocking Queues<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#An_Example-5\" >An Example<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Thread-Safe_Collections\" >Thread-Safe Collections<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Callables_Futures\" >Callables &amp; Futures<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Limitations_of_Runnable\" >The Limitations of&nbsp;Runnable<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-35\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Callable_Interface\" >The Callable Interface<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-36\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Future_Interface\" >The Future Interface<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-37\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#FutureTask\" >FutureTask<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-38\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#An_Example-6\" >An Example<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-39\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Executor_Framework\" >The Executor Framework<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-40\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Executor_Interface\" >The Executor Interface<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-41\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#ScheduledExecutorService\" >ScheduledExecutorService<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-42\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#The_Executors_Class\" >The Executors Class<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-43\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#An_Example-7\" >An Example<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-44\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/threads\/more-on-threads\/#Synchronizers\" >Synchronizers<\/a><\/li><\/ul><\/nav><\/div>\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Threads_Thread_Groups\"><\/span>Threads &amp; Thread Groups<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">What&#8217;s a ThreadGroup?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Every&nbsp;<strong>Thread<\/strong>&nbsp;is a member of a&nbsp;<strong>ThreadGroup<\/strong>.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<strong>ThreadGroup<\/strong>&nbsp;provides a mechanism for a logical grouping of multiple threads and thread groups. It is possible to manipulate some of the attributes of all the threads in a thread group in a single call.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Default_Thread_Group\"><\/span>The Default Thread Group<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">If you create a thread without specifying a&nbsp;<strong>ThreadGroup<\/strong>&nbsp;in the&nbsp;<strong>Thread<\/strong>&#8216;s constructor, the thread is placed in the same&nbsp;<strong>ThreadGroup<\/strong>&nbsp;as the thread that created it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When a Java application starts up, the Java runtime system create a <strong>ThreadGroup<\/strong> called&nbsp;<strong>main<\/strong>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Creating_a_Thread_Group\"><\/span>Creating a Thread Group<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">You can create a&nbsp;<strong>ThreadGroup<\/strong>&nbsp;(assuming that the security manager allows you to) by using a <strong>ThreadGroup<\/strong> constructor:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>public ThreadGroup(ThreadGroup parent, String name)<\/td><td>Creates a new thread group. The parent of this new group is the specified thread group.<\/td><\/tr><tr><td>public ThreadGroup(String name)<\/td><td>Constructs a new thread group. The parent of this new group is the thread group of the currently running thread.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once the&nbsp;<strong>ThreadGroup<\/strong>&nbsp;has been constructed, it is empty &#8212; that is, it contains no threads, nor thread groups.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Thread_Group_Methods\"><\/span>Thread Group Methods<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s a synopsis of the ThreadGroup methods.&nbsp;<strong><em>(Entries in bold italics are deprecated in JDK 1.2, and should not be used in&nbsp;<u>any<\/u>&nbsp;JDK version.)<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>public int activeCount()<\/td><td>Returns an estimate of the number of active threads in this thread group.<\/td><\/tr><tr><td>public int activeGroupCount()<\/td><td>Returns an estimate of the number of active groups in this thread group.<\/td><\/tr><tr><td><strong><em>public boolean allowThreadSuspension(boolean b)<\/em><\/strong><\/td><td><strong><em>Used by VM to control lowmem implicit suspension.<\/em><\/strong><\/td><\/tr><tr><td>public final void checkAccess()<\/td><td>Determines if the currently running thread has permission to modify this thread group.<\/td><\/tr><tr><td>public final destroy()<\/td><td>Destroys this thread group and all of its subgroups.<\/td><\/tr><tr><td>public int enumerate(Thread[] list)<\/td><td>Copies into the specified array every active thread in this thread group and its subgroups.<\/td><\/tr><tr><td>public int enumerate(ThreadGroup[] list, boolean recurse)<\/td><td>Copies into the specified array references to every active subgroup in this thread group.<\/td><\/tr><tr><td>public int enumerate(ThreadGroup[] list)<\/td><td>Copies into the specified array references to every active subgroup in this thread group.<\/td><\/tr><tr><td>public int enumerate(Thread[] list, boolean recurse)<\/td><td>Copies into the specified array every active thread in this thread group.<\/td><\/tr><tr><td>public final int getMaxPriority()<\/td><td>Returns the maximum priority of this thread group.<\/td><\/tr><tr><td>public final getName()<\/td><td>Returns the name of this thread group.<\/td><\/tr><tr><td>public final ThreadGroup getParent()<\/td><td>Returns the parent of this thread group<\/td><\/tr><tr><td>public final boolean isDaemon()<\/td><td>Tests if this thread group is a daemon thread group.<\/td><\/tr><tr><td>public synchronized boolean isDestroyed()<\/td><td>Tests if this thread group has been destroyed.<\/td><\/tr><tr><td>public void list()<\/td><td>Prints information about this thread group to the standard output.<\/td><\/tr><tr><td>public final boolean parentOf(ThreadGroup g)<\/td><td>Tests if this thread group is either the thread group argument or one of its ancestor thread groups.<\/td><\/tr><tr><td><strong><em>public final void resume()<\/em><\/strong><\/td><td><strong><em>Resumes all processes in this thread group.<\/em><\/strong><\/td><\/tr><tr><td>public final void setDaemon(boolean daemon)<\/td><td>Changes the daemon status of this thread group.<\/td><\/tr><tr><td>public final void setMaxPriority(int pri)<\/td><td>Sets the maximum priority of the group.<\/td><\/tr><tr><td><strong><em>public final void stop()<\/em><\/strong><\/td><td><strong><em>Stops all processes in this thread group.<\/em><\/strong><\/td><\/tr><tr><td><strong><em>public final void suspend()<\/em><\/strong><\/td><td><strong><em>Suspends all processes in this thread group.<\/em><\/strong><\/td><\/tr><tr><td>public String toString()<\/td><td>Returns a string representation of this Thread group.<\/td><\/tr><tr><td>public void uncaughtException(Thread t, Throwable e)<\/td><td>Called by the Java Virtual Machine when a thread in this thread group stops because of an uncaught exception.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Methods_that_Apply_to_the_ThreadGroup\"><\/span>Methods that Apply to the ThreadGroup<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">The methods that apply to the&nbsp;<strong>ThreadGroup<\/strong>&nbsp;itself are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>getMaxPriority<\/strong>&nbsp;and&nbsp;<strong>setMaxPriority<\/strong><\/li><li><strong>isDaemon<\/strong>&nbsp;and&nbsp;<strong>setDaemon<\/strong><\/li><li><strong>getName<\/strong><\/li><li><strong>getParent<\/strong>&nbsp;and&nbsp;<strong>parentOf<\/strong><\/li><li><strong>toString<\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The first two items in the above list apply to attributes of the <strong>ThreadGroup<\/strong> that apply to all threads&nbsp;<em><strong>subsequently created<\/strong>&nbsp;<\/em>as a member of this&nbsp;<strong>ThreadGroup<\/strong>. These attributes do not change the attributes of&nbsp;<strong>Thread<\/strong>s that already are members of the&nbsp;<strong>ThreadGroup<\/strong>.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Methods_that_Apply_to_all_Threads_in_a_ThreadGroup\"><\/span>Methods that Apply to all Threads in a ThreadGroup<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">The methods that apply to all Threads currently in the&nbsp;<code><strong>ThreadGroup<\/strong><\/code>&nbsp;are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>interrupt<\/strong><\/li><li><strong>stop,&nbsp;suspend,&nbsp;resume<\/strong> <strong><em>(deprecated in JDK 1.2, and should not be used in any JDK)<\/em><\/strong><\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Thread_Group_Tree_Navigation\"><\/span>Thread Group Tree Navigation<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ThreadGroup<\/strong>&nbsp;contains:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>A set of&nbsp;<strong>enumerate()<\/strong>&nbsp;methods which allow you to discover what threads and other thread groups are members of this&nbsp;<strong>ThreadGroup<\/strong>.<\/li><li>A&nbsp;<strong>getParent()<\/strong>&nbsp;method to determine the parent thread group of this&nbsp;<strong>ThreadGroup<\/strong><\/li><li>A&nbsp;<strong>parentOf()<\/strong>&nbsp;method to determine whether this thread group is the parent of the specified thread group.<\/li><li>An&nbsp;<strong>activeCount()<\/strong>&nbsp;method to determine the number of threads that are members of this thread group tree (recursively)<\/li><li>An&nbsp;<strong>activeGroupCount()<\/strong>&nbsp;method to return the number of thread groups that are members of this thread group tree (recursively)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of a Java application that reports on all the thread groups and threads it can find within its JVM:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\npublic class TestThreadGroup extends Thread\n{\n    public static void main(String&#x5B;] args)\n    {\n        System.out.println(doWork());\n    }\n    \n    static String doWork()\n    {\n        String s = dumpThreadGroupTree();\n        createThreadGroups();\n        s += dumpThreadGroupTree();\n        \n        return s;\n    }\n    \n    static String dumpThreadGroupTree()\n    {\n        ThreadGroup root = getRoot();\n        String s = &quot;------Dump of ThreadGroup tree-----\\n&quot;;\n        s += dump(root);\n        \n        return s;\n    }\n    \n    static void createThreadGroups()\n    {\n        ThreadGroup parentGroup = \n                new ThreadGroup(&quot;My New Parent ThreadGroup&quot;);\n        ThreadGroup childGroup = \n                new ThreadGroup(parentGroup, \n                                &quot;My New Child ThreadGroup&quot;);\n        Thread thread1 = new TestThreadGroup(parentGroup, \n                                             &quot;My First Thread&quot;);\n        parentGroup.setMaxPriority(7);\n        Thread thread2 = new TestThreadGroup(parentGroup, \n                                             &quot;My Second Thread&quot;);\n        Thread thread3 = new TestThreadGroup(childGroup, \n                                             &quot;My Third Thread&quot;);\n        childGroup.setMaxPriority(5);\n        Thread thread4 = new TestThreadGroup(childGroup, \n                                             &quot;My Fourth Thread&quot;);\n    }\n    \n    TestThreadGroup(ThreadGroup tg, String name)\n    {\n        super(tg, name);\n    }\n    \n    public void run()\n    {\n        for (int i = 0; i &lt; 10000; i++)\n        {\n            try\n            {\n                Thread.sleep(1000);\n            }\n            catch (InterruptedException e)\n            {\n                \/\/ Ignore\n            }\n        }\n    }\n    \n    static ThreadGroup getRoot()\n    {\n        ThreadGroup tg = Thread.currentThread().getThreadGroup();\n        while (true)\n        {\n            ThreadGroup parent = tg.getParent();\n            if (parent == null)\n                break;\n            tg = parent;\n        }\n        \n        return tg;\n    }\n    \n    static String dump(ThreadGroup tg)\n    {\n        String s = &quot;&quot;;\n        String indent = &quot;&quot;;\n        for (int i = 0; i &lt; m_indent; i++)\n            indent += ONE_INDENT;\n            \n        s += indent + &quot;ThreadGroup \\&quot;&quot; + tg.getName() + &quot;\\&quot;\\n&quot;;\n        s += indent + &quot; Max priority : &quot; + tg.getMaxPriority() + &quot;\\n&quot;;\n        s += indent + &quot; Daemon : &quot; + tg.isDaemon() + &quot;\\n&quot;;\n        \n        \/\/ Dump the threads in this thread group\n        m_indent++;\n        \/\/ overestimate size\n        Thread&#x5B;] threads = new Thread&#x5B;tg.activeCount()];\n        tg.enumerate(threads);\n        for (int i = 0; i &lt; threads.length; i++)\n        {\n            Thread t = threads&#x5B;i];\n            if (t == null)\n                break;\n            if (t.getThreadGroup() == tg)\n                s += dump(t);\n        }\n        \n        \/\/ Dump the thread groups in this thread group\n        ThreadGroup&#x5B;] threadGroups = \n                new ThreadGroup&#x5B;tg.activeGroupCount()]; \n                                     \/\/ overestimate size\n        tg.enumerate(threadGroups);\n        for (int i = 0; i &lt; threadGroups.length; i++)\n        {\n            ThreadGroup g = threadGroups&#x5B;i];\n            if (g == null)\n                break;\n            if (g.getParent() == tg)\n                s += dump(g);\n        }\n        --m_indent;\n        \n        return s;\n    }\n    \n    static String dump(Thread t)\n    {\n        String s = &quot;&quot;;\n        String indent = &quot;&quot;;\n        for (int i = 0; i &lt; m_indent; i++)\n            indent += ONE_INDENT;\n            \n        s += indent + &quot;Thread \\&quot;&quot; + t.getName() + &quot;\\&quot;\\n&quot;;\n        s += indent + &quot; Priority : &quot; + t.getPriority() + &quot;\\n&quot;;\n        s += indent + &quot; Daemon : &quot; + t.isDaemon() + &quot;\\n&quot;;\n        \n        return s;\n    }\n    \n    \/\/\/\/ Private data \/\/\/\/\/\/\/\/\n    private static int m_indent = 0;\n    private static final String ONE_INDENT = &quot;  &quot;;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">and here&#8217;s what it outputs on my machine, with the JVM I used:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>------Dump of ThreadGroup tree-----\n ThreadGroup \"system\"\n  Max priority : 10\n  Daemon : false\n   Thread \"Reference Handler\"\n    Priority : 10\n    Daemon : true\n   Thread \"Finalizer\"\n    Priority : 8\n    Daemon : true\n   Thread \"Signal Dispatcher\"\n    Priority : 9\n    Daemon : true\n   Thread \"Notification Thread\"\n    Priority : 9\n    Daemon : true\n   ThreadGroup \"main\"\n    Max priority : 10\n    Daemon : false\n     Thread \"main\"\n      Priority : 5\n      Daemon : false\n   ThreadGroup \"InnocuousThreadGroup\"\n    Max priority : 10\n    Daemon : false\n     Thread \"Common-Cleaner\"\n      Priority : 8\n      Daemon : true\n ------Dump of ThreadGroup tree-----\n ThreadGroup \"system\"\n  Max priority : 10\n  Daemon : false\n   Thread \"Reference Handler\"\n    Priority : 10\n    Daemon : true\n   Thread \"Finalizer\"\n    Priority : 8\n    Daemon : true\n   Thread \"Signal Dispatcher\"\n    Priority : 9\n    Daemon : true\n   Thread \"Notification Thread\"\n    Priority : 9\n    Daemon : true\n   ThreadGroup \"main\"\n    Max priority : 10\n    Daemon : false\n     Thread \"main\"\n      Priority : 5\n      Daemon : false\n     ThreadGroup \"My New Parent ThreadGroup\"\n      Max priority : 7\n      Daemon : false\n       ThreadGroup \"My New Child ThreadGroup\"\n        Max priority : 5\n        Daemon : false\n   ThreadGroup \"InnocuousThreadGroup\"\n    Max priority : 10\n    Daemon : false\n     Thread \"Common-Cleaner\"\n      Priority : 8\n      Daemon : true<\/strong><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"An_Example\"><\/span>An Example<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of the use of&nbsp;<strong>ThreadGroup<\/strong>s.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For good measure, here is a program that shows the JDK version you are running:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\npublic class TestJDK\n{\n  public static void main(String&#x5B;] args)\n  {\n    String version = System.getProperty(&quot;java.version&quot;);\n    String vendor = System.getProperty(&quot;java.vendor&quot;);\n    System.out.println(&quot;You are using Java &quot; + version +\n      &quot; from &quot; + vendor);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Which, on the system I&#8217;m currently using, outputs:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>You are using Java 15.0.2 from Oracle Corporation<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a program that uses the above TestThreadGroup class to list all the ThreadGroups and their Threads:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.awt.BorderLayout;\nimport java.awt.FlowLayout;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.util.Enumeration;\nimport java.util.EventObject;\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\n\npublic class ThreadListerFrame extends JFrame\n  implements ActionListener\n{\n  public static void main(String&#x5B;] args)\n  {\n    ThreadListerFrame frame = new ThreadListerFrame();\n    frame.setDefaultLookAndFeelDecorated(true);\n    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);\n    frame.setTitle(&quot;Thread Lister&quot;);\n    frame.setSize(300, 200);\n    frame.setVisible(true);\n  }\n    \n  public ThreadListerFrame()\n  {\n    m_dumpButton = new JButton(&quot;List Thread Groups&quot;);\n    m_clearButton = new JButton(&quot;Clear&quot;);\n    m_createButton = new JButton(&quot;Create ThreadGroups&quot;);\n    setContentPane( createLayout() );\n  }\n  \n  public void actionPerformed(ActionEvent e)\n  {\n    JButton source = (JButton)e.getSource();\n    if (source == m_dumpButton)\n      dumpData(false);\n    else\n    {\n      if (source == m_clearButton)\n        m_textarea.setText(&quot;&quot;);\n      else if (source == m_createButton)\n      {\n        m_textarea.setText(&quot;&quot;);\n        dumpData(true);\n        m_createButton.setEnabled(false);\n      }\n    }\n  }\n  \n  private void dumpData(boolean createGroups)\n  {\n    StringWriter sout = new StringWriter();\n    PrintWriter out = new PrintWriter(sout);\n    String s = &quot;&quot;;\n    if (createGroups)\n      try\n      {\n        TestThreadGroup.createThreadGroups();\n      }\n      catch(Exception e)\n      {\n        out.println(&quot;***Caught exception: &quot; + e + &quot;\\nUnable to create thread groups.&quot;);\n      }\n    try\n    {\n      s = TestThreadGroup.dumpThreadGroupTree();\n    }\n    catch(Exception e)\n    {\n      s = &quot;***Caught exception: &quot; + e + &quot;\\nUnable to dump thread group tree.&quot;;\n    }\n    out.print(s);\n    out.println();\n    \n    out.flush();\n    m_textarea.setText(sout.toString());\n  }\n  \n  public JPanel createLayout()\n  {\n    JPanel contentPane = new JPanel();\n    contentPane.setLayout( new BorderLayout() );\n    m_textarea = new JTextArea();\n    contentPane.add(new JScrollPane(m_textarea), BorderLayout.CENTER);\n    \n    JPanel buttonPanel = new JPanel();\n    buttonPanel.setLayout( new FlowLayout() );\n    contentPane.add(buttonPanel, BorderLayout.NORTH);\n    \n    m_dumpButton.addActionListener(this);\n    buttonPanel.add(m_dumpButton);\n    m_clearButton.addActionListener(this);\n    buttonPanel.add(m_clearButton);\n    m_createButton.addActionListener(this);\n    buttonPanel.add(m_createButton);\n    \n    return contentPane;\n  }\n  \n  \/\/ Private data members  \n  private JTextArea m_textarea;\n  private JButton m_dumpButton;\n  private JButton m_clearButton;\n  private JButton m_createButton;\n}ied]\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces, on my machine:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"579\" height=\"1024\" src=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-content\/uploads\/2021\/02\/Screen-Shot-2021-02-04-at-1.57.14-PM-579x1024.png\" alt=\"\" class=\"wp-image-314\" srcset=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-content\/uploads\/2021\/02\/Screen-Shot-2021-02-04-at-1.57.14-PM-579x1024.png 579w, https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-content\/uploads\/2021\/02\/Screen-Shot-2021-02-04-at-1.57.14-PM-170x300.png 170w, https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-content\/uploads\/2021\/02\/Screen-Shot-2021-02-04-at-1.57.14-PM-768x1357.png 768w, https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-content\/uploads\/2021\/02\/Screen-Shot-2021-02-04-at-1.57.14-PM-869x1536.png 869w, https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-content\/uploads\/2021\/02\/Screen-Shot-2021-02-04-at-1.57.14-PM.png 1048w\" sizes=\"auto, (max-width: 579px) 100vw, 579px\" \/><\/figure><\/div>\n\n\n\n<div style=\"height:23px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Explicit_Locks\"><\/span>Explicit Locks<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Java 1.5 (aka Java 5) introduced additional classes to support more powerful use of locks for synchronization.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s where we learn more about explicit locks&#8230;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Lock_Objects\"><\/span>Lock Objects<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">To quote from the&nbsp;<a href=\"https:\/\/docs.oracle.com\/javase\/1.5.0\/docs\/api\/java\/util\/concurrent\/locks\/Lock.html\" target=\"_blank\" rel=\"noreferrer noopener\">javadoc pages<\/a>&nbsp;for interface <strong>java.util.concurrent.locks.Lock<\/strong> :<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>A lock is a tool for controlling access to a shared resource by multiple threads. Commonly, a lock provides exclusive access to a shared resource: only one thread at a time can acquire the lock and all access to the shared resource requires that the lock be acquired first. However, some locks may allow concurrent access to a shared resource, such as the read lock of a&nbsp;<code>ReadWriteLock<\/code>.<\/strong><\/p><\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">It goes on to describe how to use such locks:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>In most cases, the following idiom should be used:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Lock theLock = ...; \ntheLock.lock();\ntry \n{\n  \/\/ access the resource protected by this lock\n} \nfinally \n{\n  theLock.unlock();\n}<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This construct guarantees that only one thread at a time can enter the <strong><em>critical section<\/em><\/strong> &#8212; the section of code between the call to lock() and the call to unlock().<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong><u>Note:<\/u><\/strong>&nbsp;It is critically important that the&nbsp;<strong>unlock()<\/strong>&nbsp;operation be placed in a finally block.&nbsp; If the code within the critical section were to throw an exception, the lock should still be unlocked.&nbsp; Without this correct placement of&nbsp;<strong>unlock()<\/strong>, other threads might be permanently blocked.<\/p><\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ReentrantLock\"><\/span>ReentrantLock<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Class&nbsp;<code><strong>ReetrantLock<\/strong><\/code>&nbsp;(<code><strong>java.util.concurrent.locks.ReentrantLock<\/strong><\/code>) is a simple implementation of the&nbsp;<code><strong>Lock<\/strong><\/code>&nbsp;interface:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<strong>ReentrantLock<\/strong>&nbsp;is&nbsp;<em>owned<\/em>&nbsp;by the thread last successfully locking, but not yet unlocking it. A thread invoking&nbsp;lock&nbsp;will return, successfully acquiring the lock, when the lock is not owned by another thread. The method will return immediately if the current thread already owns the lock. This can be checked using methods&nbsp;<code><strong>isHeldByCurrentThread()<\/strong><\/code>, and&nbsp;<strong><code>getHoldCount()<\/code>.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The constructor for this class accepts an optional&nbsp;<em><strong>fairness<\/strong><\/em>&nbsp;parameter. When set&nbsp;<strong>true<\/strong>, under contention, locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order. Programs using fair locks accessed by many threads may display lower overall throughput (i.e., are slower; often much slower) than those using the default setting, but have smaller variances in times to obtain locks and guarantee lack of starvation. Note however, that fairness of locks does not guarantee fairness of thread scheduling. Thus, one of many threads using a fair lock may obtain it multiple times in succession while other active threads are not progressing and not currently holding the lock. Also note that the untimed&nbsp;<code><strong>tryLock<\/strong><\/code>&nbsp;method does not honor the fairness setting. It will succeed if the lock is available even if other threads are waiting.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_ReentrantLock_Example\"><\/span>A ReentrantLock Example<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of the use of a&nbsp;<strong><code><strong>ReentrantLock<\/strong><\/code><\/strong>&nbsp;as one solution to the Bank Account transfer deadlock situation:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [3,4,81,82,83,84,85,86,87,88,89,90,91,142]; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n\/**\n *  This class will use an explicit lock to avoid a deadlock situation.\n *\/\npublic class ExplicitLockAccountTransfer\n{\n  public static void main(String&#x5B;] args)\n  {\n    Account a1 = new Account(&quot;Account 1&quot;, 10000);\n    Account a2 = new Account(&quot;Account 2&quot;, 30000);\n    System.out.println(&quot;Initial Balances:&quot;);\n    System.out.println(&quot; Account 1: &quot; + a1.getBalance());\n    System.out.println(&quot; Account 2: &quot; + a2.getBalance());\n    System.out.println(&quot;Transferring 5 from Account 1 to Account 2&quot;);\n    System.out.println(&quot;Transferring 20 from Account 2 to Account 1&quot;);\n    Thread threadA =\n        new TransferFundsThread(&quot;Thread A&quot;, a1, a2, 5);\n    Thread threadB =\n        new TransferFundsThread(&quot;Thread B&quot;, a2, a1, 20);\n    threadA.start();\n    threadB.start();\n  }\n}\n\nclass Account\n{\n  public Account(String name, int balance)\n  {\n    m_name = name;\n    m_balance = balance;\n  }\n  \n  public int getBalance()\n  {\n    return m_balance;\n  }\n  \n  public void setBalance(int newBalance)\n  {\n    m_balance = newBalance;\n  }\n  \n  public String getName()\n  {\n    return m_name;\n  }\n  \n  private String m_name;\n  private int    m_balance;\n}\n\nclass TransferFundsThread extends Thread\n{\n  public TransferFundsThread(String name,\n      Account from,\n      Account to,\n      int amount)\n  {\n    super(name);\n    m_from   = from;\n    m_to     = to;\n    m_amount = amount;\n  }\n  \n  public void run()\n  {\n    transferFunds();\n  }\n  \n  \/**\n   *  In order to transfer funds safely, we need to be able\n   *  to hold a lock on the single lock used to synchronize\n   *  access to the transferFunds method.\n   *\/\n  private void transferFunds()\n  {\n    m_lock.lock();\n    try\n    {\n      doTransfer();\n    }\n    finally\n    {\n      \/\/ Unlock the lock, regardless of whether\n      \/\/ an exception occurred.\n      m_lock.unlock();\n    }\n  }\n  \n  \/**\n   * Do the actual transfer of funds\n   *\/\n  private void doTransfer()\n  {\n    System.out.println(getName() +\n        &quot;: Getting balance from &quot; +\n        m_from.getName());\n    int balance1 = m_from.getBalance();\n    System.out.println(getName() +\n        &quot;: Balance from &quot; +\n        m_from.getName() +\n        &quot; = &quot; + balance1);\n    \n    System.out.println(getName() +\n        &quot;: Getting balance from &quot; +\n        m_to.getName());\n    int balance2 = m_to.getBalance();\n    System.out.println(getName() +\n        &quot;: Balance from &quot; +\n        m_to.getName() +\n        &quot; = &quot; + balance2);\n    \n    if (balance1 &gt;= m_amount)\n    {\n      System.out.println(getName() +\n          &quot;: Withdrawing funds from &quot; +\n          m_from.getName());\n      m_from.setBalance(balance1 - m_amount);\n      System.out.println(getName() +\n          &quot;: Depositing funds into &quot; +\n          m_to.getName());\n      m_to.setBalance(balance2 + m_amount);\n      \n      System.out.println(getName() +\n          &quot;: New balances are:\\n&quot; +\n          &quot;  &quot; + m_from.getName() +\n          &quot; = &quot; +\n          m_from.getBalance() + &quot;\\n&quot; +\n          &quot;  &quot; + m_to.getName() + &quot; = &quot; +\n          m_to.getBalance() );\n    }\n  }\n  \n  \/\/\/ Private data \/\/\/\n  private Account   m_from;\n  private Account   m_to;\n  private int       m_amount;\n  private Lock      m_lock = new ReentrantLock();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Which, when run produces the following output:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Initial Balances:\n Account 1: 10000\n Account 2: 30000\nTransferring 5 from Account 1 to Account 2\nTransferring 20 from Account 2 to Account 1\nThread A: Getting balance from Account 1\nThread A: Balance from Account 1 = 10000\nThread A: Getting balance from Account 2\nThread A: Balance from Account 2 = 30000\nThread A: Withdrawing funds from Account 1\nThread A: Depositing funds into Account 2\nThread A: New balances are:\n  Account 1 = 9995\n  Account 2 = 30005\nThread B: Getting balance from Account 2\nThread B: Balance from Account 2 = 30005\nThread B: Getting balance from Account 1\nThread B: Balance from Account 1 = 9995\nThread B: Withdrawing funds from Account 2\nThread B: Depositing funds into Account 1\nThread B: New balances are:\n  Account 2 = 29985\n  Account 1 = 10015<\/strong><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Notice, however, that this essentially forces each thread to wait until the other thread has completely finished.<\/p><\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Finer_Granularity\"><\/span>Finer Granularity<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">However, we are locking at a fairly coarse level.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We might want to move the locking to a finer granularity.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can use the&nbsp;<strong>trylock()<\/strong>&nbsp;method:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">boolean <strong>tryLock<\/strong>()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Acquires the lock only if it is free at the time of invocation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Acquires the lock if it is available and returns immediately with the value&nbsp;<strong>true<\/strong>. If the lock is not available then this method will return immediately with the value&nbsp;<strong>false<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A typical usage idiom for this method would be:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">      Lock lock = ...;\n      if (lock.tryLock()) \n      {\n          try \n          {\n              \/\/ manipulate protected state\n          } \n          finally \n          {\n              lock.unlock();\n          }\n      } \n      else \n      {\n          \/\/ perform alternative actions\n      }\n <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This usage ensures that the lock is unlocked if it was acquired, and doesn&#8217;t try to unlock if the lock was not acquired.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Returns:<\/strong> <strong>true<\/strong>&nbsp;if the lock was acquired and&nbsp;<strong>false<\/strong>&nbsp;otherwise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of how this might be done:<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"An_Example-2\"><\/span>An Example<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n\/**\n *  This class will use an explicit lock to avoid a deadlock situation.\n *\/\npublic class ExplicitLockAccountTransfer\n{\n  public static void main(String&#x5B;] args)\n  {\n    Account a1 = new Account(&quot;Account 1&quot;, 10000);\n    Account a2 = new Account(&quot;Account 2&quot;, 30000);\n    System.out.println(&quot;Initial Balances:&quot;);\n    System.out.println(&quot; Account 1: &quot; + a1.getBalance());\n    System.out.println(&quot; Account 2: &quot; + a2.getBalance());\n    System.out.println(&quot;Transferring 5 from Account 1 to Account 2&quot;);\n    System.out.println(&quot;Transferring 20 from Account 2 to Account 1&quot;);\n    Thread threadA =\n        new TransferFundsThread(&quot;Thread A&quot;, a1, a2, 5);\n    Thread threadB =\n        new TransferFundsThread(&quot;Thread B&quot;, a2, a1, 20);\n    threadA.start();\n    threadB.start();\n  }\n}\n\nclass Account\n{\n  public Account(String name, int balance)\n  {\n    m_name = name;\n    m_balance = balance;\n  }\n  \n  public int getBalance()\n  {\n    return m_balance;\n  }\n  \n  public void setBalance(int newBalance)\n  {\n    m_balance = newBalance;\n  }\n  \n  public String getName()\n  {\n    return m_name;\n  }\n  \n  public Lock getLock()\n  {\n    return m_lock;\n  }\n  \n  private String m_name;\n  private int    m_balance;\n  private Lock   m_lock = new ReentrantLock();\n}\n\nclass TransferFundsThread extends Thread\n{\n  public TransferFundsThread(String name,\n      Account from,\n      Account to,\n      int amount)\n  {\n    super(name);\n    m_from   = from;\n    m_to     = to;\n    m_amount = amount;\n  }\n  \n  public void run()\n  {\n    System.out.println(&quot;run: Transferring funds from &quot; + m_from.getName() +\n                       &quot; to &quot; + m_to.getName());\n    transferFunds();\n  }\n  \n  \/**\n   *  In order to transfer funds safely, we need to be able\n   *  to hold a lock on the single lock used to synchronize\n   *  access to the transferFunds method.\n   *\/\n  private void transferFunds()\n  {\n    while (true)\n    {\n      try\n      {\n        \/\/ Try to acquire the lock for the from account\n        if ( m_from.getLock().tryLock(500, TimeUnit.MILLISECONDS) )\n        {\n          try\n          {\n            \/\/ Get the balance from the from account\n            int balance = getBalance();\n            \n            \/\/ Try to acquire the lock for the to account\n            if ( m_to.getLock().tryLock(500, TimeUnit.MILLISECONDS) )\n            {\n              try\n              {\n                doTransfer(balance);\n              }\n              finally\n              {\n                \/\/ Unlock the to lock, regardless of whether\n                \/\/ an exception occurred.\n                m_to.getLock().unlock();\n              }\n              \/\/ We succeeded, so break out of the for while loop.\n              break;\n            }\n          }\n          finally\n          {\n            \/\/ Unlock the from lock, regardless of whether\n            \/\/ an exception occurred.\n            m_from.getLock().unlock();\n          }\n        }\n      }\n      catch (InterruptedException ie)\n      {\n        \/\/ Do nothing; try again\n      }\n    }\n  }\n  \n  \/**\n   * Get the balance from the to account\n   *\/\n  private int getBalance()\n  {\n    System.out.println(getName() +\n        &quot;: Getting balance from &quot; +\n        m_from.getName());\n    int fromBalance = m_from.getBalance();\n    System.out.println(getName() +\n        &quot;: Balance from &quot; +\n        m_from.getName() +\n        &quot; = &quot; + fromBalance);\n    return fromBalance;\n  }\n  \n  \/**\n   * Do the actual transfer of funds\n   *\/\n  private void doTransfer(int fromBalance)\n  {\n    System.out.println(getName() +\n        &quot;: Getting balance from &quot; +\n        m_to.getName());\n    int toBalance = m_to.getBalance();\n    System.out.println(getName() +\n        &quot;: Balance from &quot; +\n        m_to.getName() +\n        &quot; = &quot; + toBalance);\n    \n    if (fromBalance &gt;= m_amount)\n    {\n      System.out.println(getName() +\n          &quot;: Withdrawing funds from &quot; +\n          m_from.getName());\n      m_from.setBalance(fromBalance - m_amount);\n      System.out.println(getName() +\n          &quot;: Depositing funds into &quot; +\n          m_to.getName());\n      m_to.setBalance(toBalance + m_amount);\n      \n      System.out.println(getName() +\n          &quot;: New balances are:\\n&quot; +\n          &quot;  &quot; + m_from.getName() +\n          &quot; = &quot; +\n          m_from.getBalance() + &quot;\\n&quot; +\n          &quot;  &quot; + m_to.getName() + &quot; = &quot; +\n          m_to.getBalance() );\n    }\n  }\n  \n  \/\/\/ Private data \/\/\/\n  private Account   m_from;\n  private Account   m_to;\n  private int       m_amount;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Which, when run, produces the following output:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Initial Balances:\n Account 1: 10000\n Account 2: 30000\nTransferring 5 from Account 1 to Account 2\nTransferring 20 from Account 2 to Account 1\nrun: Transferring funds from Account 2 to Account 1\nThread B: Getting balance from Account 2\nThread B: Balance from Account 2 = 30000\nThread B: Getting balance from Account 1\nThread B: Balance from Account 1 = 10000\nThread B: Withdrawing funds from Account 2\nThread B: Depositing funds into Account 1\nThread B: New balances are:\n  Account 2 = 29980\n  Account 1 = 10020\nrun: Transferring funds from Account 1 to Account 2\nThread A: Getting balance from Account 1\nThread A: Balance from Account 1 = 10020\nThread A: Getting balance from Account 2\nThread A: Balance from Account 2 = 29980\nThread A: Withdrawing funds from Account 1\nThread A: Depositing funds into Account 2\nThread A: New balances are:\n  Account 1 = 10015\n  Account 2 = 29985<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This still happens to cause the threads to be serialized, but shows the use of locks of smaller granularity.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Condition_Objects\"><\/span>Condition Objects<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">So what happens if the &#8220;from&#8221; account doesn&#8217;t have enough funds?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So far, we haven&#8217;t considered this possibility. Let&#8217;s now consider it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If there are insufficient funds, we have two choices:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Give up, and report the problem, never having transferred any funds, or<\/li><li>Wait until there are sufficient funds, and then perform the transfer.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s say we choose <em>the latter<\/em>.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is a job for&nbsp;<em><strong>Condition Objects&nbsp;<\/strong><\/em>(a.k.a., for historical reasons,&nbsp;<strong><em>Condition Variables<\/em><\/strong>).&nbsp;&nbsp;<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Condition_Interface\"><\/span>The Condition Interface<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what the&nbsp;<strong>Condition<\/strong>&nbsp;interface javadoc says about itself:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Conditions (also known as&nbsp;<em>condition queues<\/em>&nbsp;or&nbsp;<em>condition variables<\/em>) provide a means for one thread to suspend execution (to &#8220;wait&#8221;) until notified by another thread that some state condition may now be true. Because access to this shared state information occurs in different threads, it must be protected, so a lock of some form is associated with the condition. The key property that waiting for a condition provides is that it&nbsp;<em>atomically<\/em>&nbsp;releases the associated lock and suspends the current thread, just like&nbsp;<strong>Object.wait<\/strong>.<\/p><p>A&nbsp;Condition&nbsp;instance is intrinsically bound to a lock. To obtain a Condition instance for a particular&nbsp;<code><strong>Lock<\/strong><\/code>&nbsp;instance use its&nbsp;<code><strong>newCondition()<\/strong><\/code>&nbsp;method.<\/p><\/blockquote>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"await\"><\/span>await()<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<pre class=\"wp-block-preformatted\">void <strong>await<\/strong>()\n   throws InterruptedException<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Causes the current thread to wait until it is signalled or&nbsp;<code><strong>interrupted<\/strong><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The lock associated with this&nbsp;Condition&nbsp;is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until&nbsp;<em>one<\/em>&nbsp;of four things happens:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Some other thread invokes the&nbsp;<code><strong>signal()<\/strong><\/code>&nbsp;method for this&nbsp;Condition&nbsp;and the current thread happens to be chosen as the thread to be awakened; or<\/li><li>Some other thread invokes the&nbsp;<code><strong>signalAll()<\/strong><\/code>&nbsp;method for this&nbsp;Condition; or<\/li><li>Some other thread&nbsp;<code><strong>interrupts<\/strong><\/code>&nbsp;the current thread, and interruption of thread suspension is supported; or<\/li><li>A &#8220;<em>spurious wakeup<\/em>&#8221; occurs<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is&nbsp;<em>guaranteed<\/em>&nbsp;to hold this lock.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the current thread:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>has its interrupted status set on entry to this method; or<\/li><li>is&nbsp;<code><strong>interrupted<\/strong><\/code>&nbsp;while waiting and interruption of thread suspension is supported,<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">then&nbsp;<code><strong>InterruptedException<\/strong><\/code>&nbsp;is thrown and the current thread&#8217;s interrupted status is cleared. It is not specified, in the first case, whether or not the test for interruption occurs before the lock is released.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are other&nbsp;<strong>await()<\/strong>&nbsp;methods with slightly different signatures, including the use of timeouts.&nbsp; See the Condition&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/docs.oracle.com\/javase\/1.5.0\/docs\/api\/java\/util\/concurrent\/locks\/Condition.html#await()\" target=\"_blank\">javadocs<\/a>&nbsp;for more detail.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"signal_signalAll\"><\/span>signal() &amp; signalAll()<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<pre class=\"wp-block-preformatted\">void <strong>signal<\/strong>()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wakes up one waiting thread.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If any threads are waiting on this condition then one is selected for waking up. That thread must then re-acquire the lock before returning from&nbsp;<strong>await<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void <strong>signalAll<\/strong>()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wakes up all waiting threads.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If any threads are waiting on this condition then they are all woken up. Each thread must re-acquire the lock before it can return from&nbsp;<strong>await<\/strong>.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"An_Example-3\"><\/span>An Example<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of the use of condition objects:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [4,17,21,22,25,26,27,32,33,34,37,69,70,71,72,73,74,75,76,77,78,83,122,123,124,125,126,200,201]; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.Condition;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n\/**\n *  This class will use an explicit lock to avoid a deadlock situation.\n *\/\npublic class ExplicitLockAccountTransfer\n{\n  public static void main(String&#x5B;] args)\n  {\n    Account a1 = new Account(&quot;Account 1&quot;, 10000);\n    Account a2 = new Account(&quot;Account 2&quot;, 30000);\n    Account a3 = new Account(&quot;Account 3&quot;, 5);\n    System.out.println(&quot;Initial Balances:&quot;);\n    System.out.println(&quot; Account 1: &quot; + a1.getBalance());\n    System.out.println(&quot; Account 2: &quot; + a2.getBalance());\n    System.out.println(&quot; Account 3: &quot; + a3.getBalance());\n    System.out.println(&quot;Transferring 100 from Account 3 to Account 1&quot;);\n    System.out.println(&quot;Transferring 5 from Account 1 to Account 2&quot;);\n    System.out.println(&quot;Transferring 20 from Account 2 to Account 1&quot;);\n    System.out.println(&quot;Transferring 500 from Account 2 to Account 3&quot;);\n    Thread threadX = \n        new TransferFundsThread(&quot;Thread X&quot;, a3, a1, 100);\n    Thread threadA =\n        new TransferFundsThread(&quot;Thread A&quot;, a1, a2, 5);\n    Thread threadB =\n        new TransferFundsThread(&quot;Thread B&quot;, a2, a1, 20);\n    Thread threadY =\n        new TransferFundsThread(&quot;Thread Y&quot;, a2, a3, 500);\n    threadX.start();\n    threadA.start();\n    threadB.start();\n    threadY.start();\n  }\n}\n\nclass Account\n{\n  public Account(String name, int balance)\n  {\n    m_name = name;\n    m_balance = balance;\n  }\n  \n  public int getBalance()\n  {\n    return m_balance;\n  }\n  \n  public void setBalance(int newBalance)\n  {\n    m_balance = newBalance;\n  }\n  \n  public String getName()\n  {\n    return m_name;\n  }\n  \n  public Lock getLock()\n  {\n    return m_lock;\n  }\n  \n  public void awaitSufficientFunds(int amount) throws InterruptedException\n  {\n    System.out.println(getName() + &quot; awaiting sufficient funds for &quot; + amount);\n    m_sufficientFunds.await(500, TimeUnit.MILLISECONDS);\n  }\n  \n  public void signalBalanceChanged()\n  {\n    m_sufficientFunds.signalAll();\n  }\n  \n  private String    m_name;\n  private int       m_balance;\n  private Lock      m_lock = new ReentrantLock();\n  private Condition m_sufficientFunds = m_lock.newCondition();\n}\n\nclass TransferFundsThread extends Thread\n{\n  public TransferFundsThread(String name,\n      Account from,\n      Account to,\n      int amount)\n  {\n    super(name);\n    m_from   = from;\n    m_to     = to;\n    m_amount = amount;\n  }\n  \n  public void run()\n  {\n    System.out.println(&quot;run: Transferring funds from &quot; + m_from.getName() +\n                       &quot; to &quot; + m_to.getName());\n    transferFunds();\n  }\n  \n  \/**\n   *  In order to transfer funds safely, we need to be able\n   *  to hold a lock on the single lock used to synchronize\n   *  access to the transferFunds method.\n   *\/\n  private void transferFunds()\n  {\n    while (true)\n    {\n      try\n      {\n        \/\/ Try to acquire the lock for the from account\n        if ( m_from.getLock().tryLock(500, TimeUnit.MILLISECONDS) )\n        {\n          try\n          {\n            \/\/ See if there are sufficient funds in the from account\n            while (getBalance() &lt; m_amount)\n            {\n              m_from.awaitSufficientFunds(m_amount);\n            }\n            \n            \/\/ Try to acquire the lock for the to account\n            if ( m_to.getLock().tryLock(500, TimeUnit.MILLISECONDS) )\n            {\n              try\n              {\n                doTransfer( getBalance() );\n              }\n              finally\n              {\n                \/\/ Unlock the to lock, regardless of whether\n                \/\/ an exception occurred.\n                m_to.getLock().unlock();\n              }\n              \/\/ We succeeded, so break out of the for while loop.\n              break;\n            }\n          }\n          finally\n          {\n            \/\/ Unlock the from lock, regardless of whether\n            \/\/ an exception occurred.\n            m_from.getLock().unlock();\n          }\n        }\n      }\n      catch (InterruptedException ie)\n      {\n        \/\/ Do nothing; try again\n      }\n    }\n  }\n  \n  \/**\n   * Get the balance from the to account\n   *\/\n  private int getBalance()\n  {\n    System.out.println(getName() +\n        &quot;: Getting balance from &quot; +\n        m_from.getName());\n    System.out.println(getName() +\n        &quot;: Balance from &quot; +\n        m_from.getName() +\n        &quot; = &quot; + m_from.getBalance());\n    return m_from.getBalance();\n  }\n  \n  \/**\n   * Do the actual transfer of funds\n   *\/\n  private void doTransfer(int fromBalance)\n  {\n    System.out.println(getName() +\n        &quot;: Getting balance from &quot; +\n        m_to.getName());\n    int toBalance = m_to.getBalance();\n    System.out.println(getName() +\n        &quot;: Balance from &quot; +\n        m_to.getName() +\n        &quot; = &quot; + toBalance);\n    \n    if (fromBalance &gt;= m_amount)\n    {\n      System.out.println(getName() +\n          &quot;: Withdrawing funds from &quot; +\n          m_from.getName());\n      m_from.setBalance(fromBalance - m_amount);\n      System.out.println(getName() +\n          &quot;: Depositing funds into &quot; +\n          m_to.getName());\n      m_to.setBalance(toBalance + m_amount);\n      \n      \/\/ Indicate to any awaiters on the to account that the balance has changed.\n      m_to.signalBalanceChanged();\n      \n      System.out.println(getName() +\n          &quot;: New balances are:\\n&quot; +\n          &quot;  &quot; + m_from.getName() +\n          &quot; = &quot; +\n          m_from.getBalance() + &quot;\\n&quot; +\n          &quot;  &quot; + m_to.getName() + &quot; = &quot; +\n          m_to.getBalance() );\n    }\n  }\n  \n  \/\/\/ Private data \/\/\/\n  private Account   m_from;\n  private Account   m_to;\n  private int       m_amount;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This, when run, produces the following output:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Initial Balances:\n Account 1: 10000\n Account 2: 30000\n Account 3: 5\nTransferring 100 from Account 3 to Account 1\nTransferring 5 from Account 1 to Account 2\nTransferring 20 from Account 2 to Account 1\nTransferring 500 from Account 2 to Account 3\nrun: Transferring funds from Account 3 to Account 1\n<strong>Thread X: Getting balance from Account 3\nThread X: Balance from Account 3 = 5\nAccount 3 awaiting sufficient funds for 100<\/strong>\nrun: Transferring funds from Account 1 to Account 2\nThread A: Getting balance from Account 1\nrun: Transferring funds from Account 2 to Account 1\nrun: Transferring funds from Account 2 to Account 3\nThread A: Balance from Account 1 = 10000\nThread B: Getting balance from Account 2\nThread B: Balance from Account 2 = 30000\n<strong>Thread X: Getting balance from Account 3\nThread X: Balance from Account 3 = 5\nAccount 3 awaiting sufficient funds for 100<\/strong>\nThread A: Getting balance from Account 1\nThread A: Balance from Account 1 = 10000\nThread B: Getting balance from Account 2\nThread B: Balance from Account 2 = 30000\n<strong>Thread X: Getting balance from Account 3\nThread X: Balance from Account 3 = 5\nAccount 3 awaiting sufficient funds for 100<\/strong>\nThread B: Getting balance from Account 2\nThread B: Balance from Account 2 = 30000\nThread B: Getting balance from Account 1\nThread B: Balance from Account 1 = 10000\nThread B: Withdrawing funds from Account 2\nThread B: Depositing funds into Account 1\nThread B: New balances are:\n  Account 2 = 29980\n  Account 1 = 10020\nThread A: Getting balance from Account 1\nThread A: Balance from Account 1 = 10020\nThread A: Getting balance from Account 1\nThread A: Balance from Account 1 = 10020\nThread A: Getting balance from Account 2\nThread A: Balance from Account 2 = 29980\nThread A: Withdrawing funds from Account 1\nThread A: Depositing funds into Account 2\nThread A: New balances are:\n  Account 1 = 10015\n  Account 2 = 29985\n<strong>Thread Y: Getting balance from Account 2\nThread Y: Balance from Account 2 = 29985\nThread Y: Getting balance from Account 2\nThread Y: Balance from Account 2 = 29985\nThread Y: Getting balance from Account 3\nThread Y: Balance from Account 3 = 5\nThread Y: Withdrawing funds from Account 2\nThread Y: Depositing funds into Account 3\nThread Y: New balances are:\n  Account 2 = 29485\n  Account 3 = 505\nThread X: Getting balance from Account 3\nThread X: Balance from Account 3 = 505\nThread X: Getting balance from Account 3\nThread X: Balance from Account 3 = 505\nThread X: Getting balance from Account 1\nThread X: Balance from Account 1 = 10015\nThread X: Withdrawing funds from Account 3\nThread X: Depositing funds into Account 1\nThread X: New balances are:\n  Account 3 = 405\n  Account 1 = 10115<\/strong><\/pre>\n\n\n\n<div style=\"height:68px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Explicit_Locks_vs_synchronized\"><\/span>Explicit Locks vs. synchronized<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">How do explicit locks compare with the use of the <code><strong>synchronized<\/strong><\/code> keyword?&nbsp; Here is a comparison:<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Synchronized_Instance_Methods\"><\/span>Synchronized Instance Methods<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">A synchronized instance method such as:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>public synchronized void transfer()\n{\n  \/\/ perform transfer\n}<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is equivalent to:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>public void transfer()\n{\n  this.<em>intrinsicLock<\/em>.lock();\n  try\n  {\n    \/\/ perform transfer\n  }\n  finally\n  {\n    this.<em>intrinsicLock<\/em>.unlock();\n  }\n}<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">where the&nbsp;<em><code><strong>intrinsicLock<\/strong><\/code><\/em>&nbsp;is the lock intrinsically associated with the object instance for that method.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Synchronized_Class_Methods\"><\/span>Synchronized Class Methods<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">A synchronized class (static) method is similar to the above, except that the intrinsic lock is the one associated with the class&#8217;s associated&nbsp;<strong><em>class object<\/em><\/strong>.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_wait_Method\"><\/span>The wait() Method<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">A call to the&nbsp;<code><strong>wait()<\/strong><\/code>&nbsp;method is equivalent to:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong><em>intrinsicCondition<\/em>.await();<\/strong><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_notifyAll_Method\"><\/span>The notifyAll() Method<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">A call to the&nbsp;<code><strong>notifyAll()<\/strong><\/code>&nbsp;method is equivalent to:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong><em>intrinsicCondition<\/em>.signalAll();<\/strong><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Pros_and_Cons\"><\/span>Pros and Cons<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Using the <em>synchronized<\/em> mechanism tends to be much more concise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using <em>explicit locks and conditions<\/em> is much more flexible.&nbsp; For example, using&nbsp;<code><em>synchronized<\/em><\/code>&nbsp;is subject to the following restrictions:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>You cannot interrupt a thread that is trying to acquire a lock<\/li><li>You cannot specify a timeout when trying to acquire a lock<\/li><li>Having a single condition per lock can be less than ideal.<\/li><\/ul>\n\n\n\n<div style=\"height:67px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ReadWrite_Locks\"><\/span>Read\/Write Locks<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Another kind of lock provided by Java 5 and beyond is a&nbsp;<code><strong>ReadWriteLock<\/strong><\/code>.&nbsp; This is an interface (<code><strong>java.util.concurrent.locks.ReadWriteLock<\/strong><\/code>), which&nbsp;<a href=\"https:\/\/docs.oracle.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/locks\/ReadWriteLock.html\" target=\"_blank\" rel=\"noreferrer noopener\">describes itself<\/a>&nbsp;thusly:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>A&nbsp;<strong>ReadWriteLock<\/strong>&nbsp;maintains a pair of associated&nbsp;<code><strong>locks<\/strong><\/code>, one for read-only operations and one for writing. The&nbsp;<code><strong>read lock<\/strong><\/code>&nbsp;may be held simultaneously by multiple reader threads, so long as there are no writers. The&nbsp;<code><strong>write lock<\/strong><\/code>&nbsp;is exclusive.<\/p><\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>All&nbsp;<strong>ReadWriteLock<\/strong>&nbsp;implementations must guarantee that the memory synchronization effects of&nbsp;<strong>writeLock<\/strong>&nbsp;operations (as specified in the&nbsp;<code><strong>Lock<\/strong><\/code>&nbsp;interface) also hold with respect to the associated&nbsp;<strong>readLock<\/strong>. That is, a thread successfully acquiring the read lock will see all updates made upon previous release of the write lock.<\/p><\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>A read-write lock allows for a greater level of concurrency in accessing shared data than that permitted by a mutual exclusion lock. It exploits the fact that while only a single thread at a time (a&nbsp;<em><strong>writer<\/strong><\/em>&nbsp;thread) can modify the shared data, in many cases any number of threads can concurrently read the data (hence&nbsp;<em><strong>reader<\/strong><\/em>&nbsp;threads). In theory, the increase in concurrency permitted by the use of a read-write lock will lead to performance improvements over the use of a mutual exclusion lock. In practice this increase in concurrency will only be fully realized on a multi-processor, and then only if the access patterns for the shared data are suitable.<\/p><\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Whether or not a read-write lock will improve performance over the use of a mutual exclusion lock depends on the frequency that the data is read compared to being modified, the duration of the read and write operations, and the contention for the data &#8211; that is, the number of threads that will try to read or write the data at the same time. For example, a collection that is initially populated with data and thereafter infrequently modified, while being frequently searched (such as a directory of some kind) is an ideal candidate for the use of a read-write lock. However, if updates become frequent then the data spends most of its time being exclusively locked and there is little, if any increase in concurrency. Further, if the read operations are too short the overhead of the read-write lock implementation (which is inherently more complex than a mutual exclusion lock) can dominate the execution cost, particularly as many read-write lock implementations still serialize all threads through a small section of code. Ultimately, only profiling and measurement will establish whether the use of a read-write lock is suitable for your application.<\/p><\/blockquote>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ReentrantReadWriteLock\"><\/span>ReentrantReadWriteLock<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>ReadWriteLock<\/strong><\/code>&nbsp;interface defines the following methods:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><th>Method<\/th><th>Description<\/th><\/tr><tr><td><code><strong>Lock readLock()<\/strong><\/code><\/td><td>Returns the lock used for reading.<\/td><\/tr><tr><td><code><strong>Lock writeLock()<\/strong><\/code><\/td><td>Returns the lock used for writing.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Java provides an implementation of <code><strong>ReadWriteLock<\/strong><\/code>,&nbsp;<code><strong>java.util.concurrent.locks.ReentrantReadWriteLock<\/strong><\/code>, whose API javadocs you can find&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/docs.oracle.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/locks\/ReentrantReadWriteLock.html\" target=\"_blank\">here<\/a>.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"An_Example-4\"><\/span>An Example<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of how you might use this feature:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.util.Map;\nimport java.util.TreeMap;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\n\n\/**\n * A Dictionary class that uses a ReentrantReadWriteLock to provide\n * convenient and controlled reader and writer synchronized access.\n *\n * (Follows the example in the ReentrantReadWriteLock class javadocs.)\n *\n *\/\npublic class ReadWriteDictionary\n{\n  public Data get(String key)\n  {\n    readLock.lock();\n    try\n    {\n      return theMap.get(key);\n    }\n    finally\n    {\n      readLock.unlock();\n    }\n  }\n  \n  public String&#x5B;] allKeys()\n  {\n    readLock.lock();\n    try\n    {\n      return (String&#x5B;]) theMap.keySet().toArray();\n    }\n    finally\n    {\n      readLock.unlock();\n    }\n  }\n  \n  public Data put(String key, Data value)\n  {\n    writeLock.lock();\n    try\n    {\n      return theMap.put(key, value);\n    }\n    finally\n    {\n      writeLock.unlock();\n    }\n  }\n  \n  public void clear()\n  {\n    writeLock.lock();\n    try\n    {\n      theMap.clear();\n    }\n    finally\n    {\n      writeLock.unlock();\n    }\n  }\n  \n  \/\/\/\/\/\/ Private data \/\/\/\/\/\n  private final Map&lt;String, Data&gt; theMap = new TreeMap&lt;String, Data&gt;();\n  private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();\n  private final Lock readLock = rwl.readLock();\n  private final Lock writeLock = rwl.writeLock();\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\n\/**\n * Dummy Data class for ReadWriteDictionary.\n *\/\npublic class Data\n{\n  \/**\n   * Creates a new instance of Data\n   *\/\n  public Data()\n  {\n  }\n  \n  \/\/ ...\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Note how the methods that read data from the dictionary are protected by the read lock, while methods that implement changes to the dictionary are protected by the write lock.&nbsp; The&nbsp;<code><strong>ReentrantReadWriteLock<\/strong><\/code>&nbsp;class provides the necessary coordination.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Atomic_Variables\"><\/span>Atomic Variables<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Java 5 also introduced a package,&nbsp;<code><strong>java.util.concurrent.atomic<\/strong><\/code>, that contains some useful classes that support lock-free thread-safe programming on single variables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/docs.oracle.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/atomic\/package-summary.html\" target=\"_blank\" rel=\"noreferrer noopener\">Here<\/a>&nbsp;is the javadoc for this package.&nbsp; It lists the classes and some documentation thereof.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s worthy of some inspection.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Blocking_Queues\"><\/span>Blocking Queues<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A common need, when dealing with multiple threads, is for a thread-safe coordinated queue into which you can place items of work, and from which a pool of threads can pick up those items of work and process them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is such a common need that Java 5 (and beyond) now provides such a set of queues.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All these queues implement the interface <code><strong><a rel=\"noreferrer noopener\" href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/BlockingQueue.html\" target=\"_blank\">java.util.concurrent.BlockingQueue<\/a><\/strong><\/code>, or <code><strong><a rel=\"noreferrer noopener\" href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/BlockingDeque.html\" target=\"_blank\">java.util.concurrent.BlockingDeque<\/a><\/strong><\/code> (for a double-ended queue version).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The queues implemented in the package&nbsp;<code><strong><a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/package-summary.html\" target=\"_blank\" rel=\"noreferrer noopener\">java.util.concurrent<\/a><\/strong><\/code>&nbsp;include:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code><strong>ArrayBlockingQueue<\/strong><\/code>&nbsp;&#8212; A bounded blocking queue backed by an array.<\/li><li><code><strong>LinkedBlockingQueue<\/strong><\/code>&nbsp;&#8212; An optionally-bounded blocking queue based on linked nodes.<\/li><li><code><strong>LinkedBlockingDeque<\/strong><\/code>&nbsp;&#8212; An optionally-bounded blocking deque based on linked nodes.<\/li><li><code><strong>PriorityBlockingQueue<\/strong><\/code>&nbsp;&#8212; An unbounded blocking queue that uses the same ordering rules as class&nbsp;<code><strong>PriorityQueue<\/strong><\/code>&nbsp;and supplies blocking retrieval operations.<\/li><li><code><strong>DelayQueue<\/strong><\/code>&nbsp;&#8212; An unbounded blocking queue of&nbsp;<strong>Delayed<\/strong>&nbsp;elements, in which an element can only be taken when its delay has expired.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"An_Example-5\"><\/span>An Example<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of the use of a blocking queue, modified from <em>Core Java, Vol 1, Fundamentals<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It uses a blocking queue to coordinate communications between a <strong>FileEnumerationTask<\/strong>, and a set of threads each running a <strong>SearchFileTask<\/strong>, in order to find instances of a specified keyword in all the <strong>.java<\/strong> files within a specified directory and its subdirectories.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.util.concurrent.BlockingQueue;\n\n\/**\n * Class to enumerate all files in a directory and its subdirectories.\n *\/\npublic class FileEnumerationTask implements Runnable\n{\n  \/**\n   * A sentinel to indicate to the worker thread that there is\n   * no more work to do.\n   *\/\n  public static final File END_WORK = new File(&quot;&quot;);\n  \n  \/**\n   * Creates a new instance of FileEnumerationTask\n   *\n   * @param queue the blocking queue to which the enumerated files are added\n   * @param startAt the directory in which to start the enumeration\n   *\/\n  public FileEnumerationTask(BlockingQueue&lt;File&gt; queue, File startAt)\n  {\n    m_queue = queue;\n    m_startingDirectory = startAt;\n  }\n\n  \/**\n   * The method that does the work of the thread.\n   *\/\n  public void run()\n  {\n    try\n    {\n      enumerate(m_startingDirectory);\n      m_queue.put(END_WORK);  \/\/ Flag\/sentinel\n    }\n    catch (InterruptedException ie)\n    {\n      \/\/ Do nothing\n    }\n  }\n  \n  \/**\n   * Method to recursively enumerate all the files in a given\n   * directory and its subdirectories\n   * \n   * @param directory the directory in which to start.\n   *\/\n  private void enumerate(File directory) throws InterruptedException\n  {\n    \/\/ For simplicity, restrict our interest in .java files only\n    File&#x5B;] files = directory.listFiles( new FileFilter()\n      {\n        public boolean accept(File file)\n        {\n          return file.isDirectory() || file.getName().endsWith(&quot;.java&quot;);\n        }\n      }\n    );\n    for (File file : files)\n    {\n      if (file.isDirectory())\n        enumerate(file);\n      else\n        m_queue.put(file);\n    }\n  }\n  \n  \/\/\/\/\/ Private data \/\/\/\/\/\n  private BlockingQueue&lt;File&gt; m_queue;\n  private File m_startingDirectory;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.Scanner;\nimport java.util.concurrent.BlockingQueue;\n\n\/**\n * Class to search a file for a specified keyword.\n *\/\npublic class SearchFileTask implements Runnable\n{\n  \/**\n   * Creates a new instance of SearchFileTask\n   *\n   * @param queue the queue from which to take files\n   * @param keyword the keyword to search for\n   *\/\n  public SearchFileTask(BlockingQueue&lt;File&gt; queue, String keyword)\n  {\n    m_queue = queue;\n    m_keyword = keyword;\n  }\n  \n  \/**\n   * The method that does the work for the thread\n   *\/\n  public void run()\n  {\n    try\n    {\n      boolean done = false;\n      while (!done)\n      {\n        File file = m_queue.take();\n        if (file == FileEnumerationTask.END_WORK)\n        {\n          m_queue.put(file);\n          done = true;\n        }\n        else\n        {\n          search(file);\n        }\n      }\n    }\n    catch (IOException ioe)\n    {\n      ioe.printStackTrace();\n    }\n    catch (InterruptedException ie)\n    {\n      \/\/ Do nothing\n    }\n  }\n  \n  \/**\n   * Searchs a file for a given keyword, and prints all matching lines.\n   *\n   * @param file the file to search\n   *\/\n  private void search(File file) throws IOException\n  {\n    Scanner in = null;\n    try\n    {\n      in = new Scanner(new FileReader(file));\n      int lineNumber = 0;\n      while (in.hasNextLine())\n      {\n        lineNumber++;\n        String line = in.nextLine();\n        if (line.contains(m_keyword))\n        {\n          System.out.printf(&quot;%s &#x5B;%d] : %s\\n&quot;,\n            file.getPath(), lineNumber, line);\n        }\n      }\n    }\n    finally\n    {\n      in.close();\n    }\n  }\n  \n  \/\/\/\/ Private data \/\/\/\/\/\n  private BlockingQueue&lt;File&gt; m_queue;\n  private String m_keyword;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.io.File;\nimport java.util.Scanner;\nimport java.util.concurrent.ArrayBlockingQueue;\nimport java.util.concurrent.BlockingQueue;\n\n\/**\n * Class to demonstrate the use of a BlockingQueue\n *\/\npublic class BlockingQueueDemo\n{\n  \/**\n   * Main entry point\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    Scanner in = new Scanner(System.in);\n    System.out.print(&quot;Enter starting directory: &quot;);\n    String directory = in.nextLine();\n    System.out.print(&quot;Enter keyword to search for: &quot;);\n    String keyword = in.nextLine();\n    \n    final int FILE_QUEUE_SIZE = 10;\n    final int SEARCH_THREADS = 100;\n    \n    BlockingQueue&lt;File&gt; queue = new ArrayBlockingQueue&lt;File&gt;(FILE_QUEUE_SIZE);\n    \n    FileEnumerationTask enumerator = new FileEnumerationTask(queue, new File(directory));\n    new Thread(enumerator).start();\n    \n    for (int i = 1; i &lt;= SEARCH_THREADS; i++)\n    {\n      new Thread( new SearchFileTask(queue, keyword) ).start();\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of the output of this program (we searched for the keyword&nbsp;<code><strong>for<\/strong><\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code smallest-font\"><code>...\\Threads\\src\\threads\\CountDownProgress.java &#91;5] :  * for the CountDownThread.\n...\\Threads\\src\\threads\\CountDownThreadTester.java &#91;17] :     for (int i = 1; i &lt;= threadCount; i++)\n...\\Threads\\src\\threads\\BlockingQueueDemo.java &#91;21] :     System.out.print(\"Enter keyword to search for: \");\n...\\Threads\\src\\threads\\CountDownRunnable.java &#91;20] :       for (int i = m_countDown; i >= 0; i--)\n...\\Threads\\src\\threads\\Data.java &#91;4] :  * Dummy Data class for ReadWriteDictionary.\n...\\Threads\\src\\threads\\CountDownRunnableTester.java &#91;17] :     for (int i = 1; i &lt;= threadCount; i++)\n...\\Threads\\src\\threads\\FindFactors.java &#91;13] :     \/\/ one for each RANGE of divisors to test for.\n...\\Threads\\src\\threads\\LanguageBigots.java &#91;19] :         for (int i = 0; i &lt; 5; i++)\n...\\Threads\\src\\threads\\ClockApplet.java &#91;70] :               m_timeLabel.setText(dateFormatter.format(date));\n...\\Threads\\src\\threads\\SearchFileTask.java &#91;10] :  * Class to search a file for a specified keyword.\n...\\Threads\\src\\threads\\Producer.java &#91;45] :       \/\/ Loop, asking for input from the user until EOF\n...\\Threads\\src\\threads\\ExplicitLockAccountTransfer3.java &#91;71] :     System.out.println(getName() + \" awaiting sufficient funds for \" + amount);\n...\\Threads\\src\\threads\\TestThreadGroup.java &#91;54] :     for (int i = 0; i &lt; 10000; i++)\n...\\Threads\\src\\threads\\CountDownThread.java &#91;23] :         sleep(1000);    \/\/ Sleep for 1 second\n...\\Threads\\src\\threads\\ThreadListerApplet.java &#91;29] :   public void actionPerformed(ActionEvent e)\n...\\Threads\\src\\unsynchronized\\SteamBoiler.java &#91;16] :     for (int burner = 0; burner &lt; BURNER_COUNT; burner++)\n...\\Threads\\src\\threads\\FileEnumerationTask.java &#91;63] :     for (File file : files)\n...\\Threads\\src\\threads\\ExplicitLockAccountTransfer2.java &#91;94] :         \/\/ Try to acquire the lock for the from account\n...\\Threads\\src\\threads\\SteamBoilerApplet.java &#91;55] :       public void actionPerformed(ActionEvent event)\n...\\Threads\\src\\threads\\PipedProducer.java &#91;53] :       \/\/ Loop, asking for input from the user until EOF\n...\\Threads\\src\\threads\\SteamBoiler.java &#91;16] :     for (int burner = 0; burner &lt; BURNER_COUNT; burner++)\n...\\Threads\\src\\threads\\BlockingQueueDemo.java &#91;32] :     for (int i = 1; i &lt;= SEARCH_THREADS; i++)\n...\\Threads\\src\\unsynchronized\\SteamBoilerApplet.java &#91;56] :       public void actionPerformed(ActionEvent event)\n...\\Threads\\src\\threads\\CountDownRunnable.java &#91;22] :         Thread.sleep(1000);    \/\/ Sleep for 1 second\n...\\Threads\\src\\threads\\FindFactors.java &#91;17] :     for (int thread = 0; thread &lt; threadCount; thread++)\n...\\Threads\\src\\threads\\SearchFileTask.java &#91;18] :    * @param keyword the keyword to search for\n...\\Threads\\src\\threads\\Producer.java &#91;68] :  *  This is a Consumer thread that waits for input from\n...\\Threads\\src\\threads\\ExplicitLockAccountTransfer3.java &#91;117] :         \/\/ Try to acquire the lock for the from account\n...\\Threads\\src\\threads\\TestThreadGroup.java &#91;85] :     for (int i = 0; i &lt; m_indent; i++)\n...\\Threads\\src\\threads\\ThreadListerApplet.java &#91;75] :     for(Enumeration e = appContext.getApplets(); \n...\\Threads\\src\\unsynchronized\\SteamBoiler.java &#91;41] :     for (int burner = 0; burner &lt; BURNER_COUNT; burner++)\n...\\Threads\\src\\threads\\ExplicitLockAccountTransfer2.java &#91;102] :             \/\/ Try to acquire the lock for the to account\n...\\Threads\\src\\threads\\SteamBoilerApplet.java &#91;70] :       public void actionPerformed(ActionEvent event)\n...\\Threads\\src\\threads\\PipedProducer.java &#91;76] :  *  This is a PipedConsumer thread that waits for input from\n...\\Threads\\src\\threads\\SteamBoiler.java &#91;41] :     for (int burner = 0; burner &lt; BURNER_COUNT; burner++)\n...\\Threads\\src\\unsynchronized\\SteamBoilerApplet.java &#91;71] :       public void actionPerformed(ActionEvent event)\n...\\Threads\\src\\threads\\FindFactors.java &#91;46] :     for (long div = m_from; div &lt;= m_to &amp;&amp; div &lt; m_number; div++)\n...\\Threads\\src\\threads\\SearchFileTask.java &#91;27] :    * The method that does the work for the thread\n...\\Threads\\src\\threads\\ExplicitLockAccountTransfer3.java &#91;128] :             \/\/ Try to acquire the lock for the to account\n...\\Threads\\src\\threads\\TestThreadGroup.java &#91;97] :     for (int i = 0; i &lt; threads.length; i++)\n...\\Threads\\src\\unsynchronized\\SteamBoiler.java &#91;45] :         burners&#91;burner].join();     \/\/ Wait for thread to finish\n...\\Threads\\src\\threads\\ExplicitLockAccountTransfer2.java &#91;115] :               \/\/ We succeeded, so break out of the for while loop.\n...\\Threads\\src\\threads\\SteamBoiler.java &#91;45] :         burners&#91;burner].join();     \/\/ Wait for thread to finish\n...\\Threads\\src\\threads\\SearchFileTask.java &#91;59] :    * Searchs a file for a given keyword, and prints all matching lines.\n...\\Threads\\src\\threads\\ExplicitLockAccountTransfer3.java &#91;141] :               \/\/ We succeeded, so break out of the for while loop.\n...\\Threads\\src\\threads\\TestThreadGroup.java &#91;111] :     for (int i = 0; i &lt; threadGroups.length; i++)\n...\\Threads\\src\\threads\\TestThreadGroup.java &#91;128] :     for (int i = 0; i &lt; m_indent; i++)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;(Note that the&nbsp;<code><strong>...\\<\/strong><\/code>&nbsp;represents uninteresting, machine-specific path information.)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Thread-Safe_Collections\"><\/span>Thread-Safe Collections<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In addition to the&nbsp;<code><strong>BlockingQueue<\/strong><\/code>&nbsp;interface, Java 5 also added new collection classes (<strong><em>concurrent collections<\/em><\/strong>), including the&nbsp;<code><strong>Queue<\/strong><\/code>&nbsp;interface, as well as high-performance concurrent implementations of&nbsp;<code><strong>Map<\/strong><\/code>,&nbsp;<code><strong>List<\/strong><\/code>, and&nbsp;<code>Queue<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Specifically:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code><strong>ConcurrentMap<\/strong><\/code>&nbsp;interface &#8212; A&nbsp;<code><strong>Map<\/strong><\/code>&nbsp;providing additional atomic&nbsp;<strong>putIfAbsent<\/strong>,&nbsp;<strong>remove<\/strong>, and&nbsp;<strong>replace<\/strong>&nbsp;methods.<\/li><li><code><strong>ConcurrentNavigableMap<\/strong><\/code>&nbsp;interface &#8212; A&nbsp;<code>ConcurrentMap<\/code>&nbsp;supporting&nbsp;<code>NavigableMap<\/code>&nbsp;operations, and recursively so for its navigable sub-maps.<\/li><li><code><strong>ConcurrentHashMap<\/strong><\/code>&nbsp;&#8212; A hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates.<\/li><li><code><strong>ConcurrentLinkedQueue<\/strong><\/code>&nbsp;&#8212; An unbounded thread-safe&nbsp;<strong>queue<\/strong>&nbsp;based on linked nodes.<\/li><li><code><strong>ConcurrentSkipListMap<\/strong><\/code>&nbsp;&#8212; A scalable concurrent&nbsp;<code><strong>ConcurrentNavigableMap<\/strong><\/code>&nbsp;implementation.<\/li><li><code><strong>ConcurrentSkipListSet<\/strong><\/code>&nbsp;&#8212; A scalable concurrent&nbsp;<code>NavigableSet<\/code>&nbsp;implementation based on a&nbsp;<code>ConcurrentSkipListMap<\/code>.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Also, there are copy-on-write thread-safe collections:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code><strong>CopyOnWriteArrayList<\/strong><\/code>&nbsp;&#8212;&nbsp; A thread-safe variant of&nbsp;<code><strong>ArrayList<\/strong><\/code>&nbsp;in which all mutative operations (<strong>add<\/strong>,&nbsp;<strong>set<\/strong>, and so on) are implemented by making a fresh copy of the underlying array.<\/li><li><code><strong>CopyOnWriteArraySet<\/strong><\/code>&nbsp;&#8212; A&nbsp;<code><strong>Set<\/strong><\/code>&nbsp;that uses an internal&nbsp;<code><strong>CopyOnWriteArrayList<\/strong><\/code>&nbsp;for all of its operations.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Callables_Futures\"><\/span>Callables &amp; Futures<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Limitations_of_Runnable\"><\/span>The Limitations of&nbsp;<code><strong>Runnable<\/strong><\/code><span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>Runnable<\/strong><\/code>&nbsp;interface looks like this (minus comments, etc.):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>public interface Runnable \n{\n    public void run();\n}<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">which means that it has some limitations:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>you can pass no parameters to the thread<\/li><li>the thread cannot return a value<\/li><li>the thread may not throw a checked exception.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Callable_Interface\"><\/span>The Callable Interface<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>Callable<\/strong><\/code>&nbsp;interface addresses two of these limitations: it can return a value, and it may throw a checked exception.&nbsp; Because the value being returned must have a type,&nbsp;<code><strong>Callable<\/strong><\/code>&nbsp;is a parameterized type:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public interface Callable&lt;V&gt;\n{\n    V call() throws Exception\n}<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Future_Interface\"><\/span>The Future Interface<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>Future<\/strong><\/code>&nbsp;interface holds the result of an asynchronous operation.&nbsp; You can start a computation, and then pass on the&nbsp;<code><strong>Future<\/strong><\/code>&nbsp;object representing the eventual result of that computation.&nbsp; The code that you pass it on to can determine when the computation has done, and the obtain the result without further assistance from you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here are the methods declared in the&nbsp;<code><strong>Future<\/strong><\/code>&nbsp;interface<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Return type<\/th><th>Method<\/th><\/tr><\/thead><tbody><tr><td><code>&nbsp;boolean<\/code><\/td><td><code><strong>cancel<\/strong>(boolean&nbsp;mayInterruptIfRunning)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attempts to cancel execution of this task.<\/td><\/tr><tr><td><code>&nbsp;<a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/Future.html\">V<\/a><\/code><\/td><td><code><strong>get<\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Waits if necessary for the computation to complete, and then retrieves its result.<\/td><\/tr><tr><td><code>&nbsp;<a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/Future.html\">V<\/a><\/code><\/td><td><code><strong>get<\/strong>(long&nbsp;timeout, TimeUnit&nbsp;unit)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.<\/td><\/tr><tr><td><code>&nbsp;boolean<\/code><\/td><td><code><strong>isCancelled<\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns&nbsp;true&nbsp;if this task was cancelled before it completed normally.<\/td><\/tr><tr><td><code>&nbsp;boolean<\/code><\/td><td><code><strong>isDone<\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns&nbsp;true&nbsp;if this task completed.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"FutureTask\"><\/span>FutureTask<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>FutureTask<\/strong><\/code>&nbsp;class implements a cancellable asynchronous computation. This class provides a base implementation of&nbsp;<code><strong>Future<\/strong><\/code>, with methods to start and cancel a computation, query to see if the computation is complete, and retrieve the result of the computation. The result can only be retrieved when the computation has completed; the&nbsp;get&nbsp;method will block if the computation has not yet completed. Once the computation has completed, the computation cannot be restarted or cancelled.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>FutureTask<\/strong><\/code>&nbsp;class has the following constructors:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code><strong>FutureTask<\/strong>(Callable&lt;V&gt;&nbsp;callable)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a&nbsp;FutureTask&nbsp;that will upon running, execute the given&nbsp;Callable.<\/td><\/tr><tr><td><code><strong>FutureTask<\/strong>(Runnable&nbsp;runnable, V&nbsp;result)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a&nbsp;FutureTask&nbsp;that will upon running, execute the given&nbsp;Runnable, and arrange that&nbsp;get&nbsp;will return the given result on successful completion.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">which means that a&nbsp;<strong>FutureTask<\/strong>&nbsp;can be used to wrap a <code><strong>Callable<\/strong><\/code> or <code><strong>Runnable<\/strong><\/code> object. Because&nbsp;<strong>FutureTask<\/strong>&nbsp;implements&nbsp;<strong>Runnable<\/strong>, it can be supplied to a Thread instance to run within a thread.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In addition to implementing the methods specified in the&nbsp;<code><strong>Future<\/strong><\/code>&nbsp;interface, the&nbsp;<code><strong>FutureTask<\/strong><\/code>&nbsp;class implements the following methods:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>protected &nbsp;void<\/code><\/td><td><code><strong><a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/FutureTask.html#done%28%29\">done<\/a><\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Protected method invoked when this task transitions to state&nbsp;isDone&nbsp;(whether normally or via cancellation).<\/td><\/tr><tr><td><code>&nbsp;void<\/code><\/td><td><code><strong><a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/FutureTask.html#run%28%29\">run<\/a><\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets this Future to the result of its computation unless it has been cancelled.<\/td><\/tr><tr><td><code>protected &nbsp;boolean<\/code><\/td><td><code><strong><a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/FutureTask.html#runAndReset%28%29\">runAndReset<\/a><\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Executes the computation without setting its result, and then resets this Future to initial state, failing to do so if the computation encounters an exception or is cancelled.<\/td><\/tr><tr><td><code>protected &nbsp;void<\/code><\/td><td><code><strong><a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/FutureTask.html#set%28V%29\">set<\/a><\/strong>(<a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/FutureTask.html\">V<\/a>&nbsp;v)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the result of this Future to the given value unless this future has already been set or has been cancelled.<\/td><\/tr><tr><td><code>protected &nbsp;void<\/code><\/td><td><code><strong><a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/FutureTask.html#setException%28java.lang.Throwable%29\">setException<\/a><\/strong>(<a href=\"http:\/\/java.sun.com\/javase\/6\/docs\/api\/java\/lang\/Throwable.html\">Throwable<\/a>&nbsp;t)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Causes this future to report an&nbsp;ExecutionException&nbsp;with the given throwable as its cause, unless this Future has already been set or has been cancelled.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"An_Example-6\"><\/span>An Example<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of the use of&nbsp;<code><strong>Callable<\/strong><\/code>,&nbsp;<code><strong>Future<\/strong><\/code>, and&nbsp;<code><strong>FutureTask<\/strong><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This example (modified from an example in <em>Core Java, Vol. 1, Fundamentals<\/em>) is similar to the earlier&nbsp;<code><strong>BlockingQueueDemo<\/strong><\/code>&nbsp;example, except that it counts the number of files that contain a specified keyword.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [31,32,33,34,87,88,89,90,91,92,93]; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Scanner;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.FutureTask;\n\n\/**\n * A class to represent a Callable value that returns the count\n * of files in a directory and its subdirectories that contain\n * a specified keyword.\n *\/\npublic class MatchCounter implements Callable&lt;Integer&gt;\n{\n  \/**\n   * Main entry point\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    Scanner in = new Scanner(System.in);\n    System.out.print(&quot;Starting directory? &quot;);\n    String directory = in.nextLine();\n    System.out.print(&quot;Keyword? &quot;);\n    String keyword = in.nextLine();\n    MatchCounter counter = new MatchCounter(new File(directory), keyword);\n    FutureTask&lt;Integer&gt; task = new FutureTask&lt;Integer&gt;(counter);\n    Thread thread = new Thread(task);\n    thread.start();\n    try\n    {\n      System.out.println( task.get() + &quot; files contained &#039;&quot; + keyword + &quot;&#039;&quot;);\n    }\n    catch (ExecutionException ee)\n    {\n      ee.printStackTrace();\n    }\n    catch (InterruptedException ie)\n    {\n      System.err.println(&quot;Execution interrupted&quot;);\n    }\n  }\n  \n  \/**\n   * Creates a new instance of MatchCounter.\n   *\n   * @param directory the directory in which to start the search\n   * @param keyword the keyword to search for.\n   *\/\n  public MatchCounter(File directory, String keyword)\n  {\n    m_directory = directory;\n    m_keyword = keyword;\n  }\n\n  \/**\n   * Implements the required Callable method\n   *\/\n  public Integer call()\n  {\n    m_count = 0;\n    try\n    {\n      \/\/ Get list of files in current directory that match the file filter\n      File&#x5B;] files = m_directory.listFiles( new FileFilter()\n        {\n          public boolean accept(File file)\n          {\n            return file.isDirectory() || file.getName().endsWith(&quot;.java&quot;);\n          }\n        }\n      );\n      \n      \/\/ Create a results array\n      ArrayList&lt;Future&lt;Integer&gt;&gt; results = new ArrayList&lt;Future&lt;Integer&gt;&gt;();\n      \n      \/\/ Go through the files, doing a recursive and multi-threaded search.\n      for (File file : files)\n      {\n        if (file.isDirectory())\n        {\n          \/\/ Use another MatchCounter and another thread to search\n          \/\/ this directory.\n          MatchCounter counter = new MatchCounter(file, m_keyword);\n          FutureTask&lt;Integer&gt; task = new FutureTask&lt;Integer&gt;(counter);\n          results.add(task);\n          Thread thread = new Thread(task);\n          thread.start();\n        }\n        else\n        {\n          if (search(file))\n            m_count++;\n        }\n      }\n      \n      \/\/ Go through the Future results and accumulate the counts\n      for (Future&lt;Integer&gt; result : results)\n      {\n        try\n        {\n          m_count += result.get(); \/\/ Blocks until result available\n        }\n        catch (ExecutionException ee)\n        {\n          ee.printStackTrace();\n        }\n      }\n    }\n    catch (InterruptedException ie)\n    {\n      \/\/ Ignore\n    }\n    return m_count;\n  }\n\n  \/**\n   * Searches the specified file for a given keyword.\n   *\n   * @param file the file to search\n   * @return true if the keyword was found in the file.\n   *\/\n  private boolean search(File file)\n  {\n    Scanner in = null;\n    boolean found = false;\n    try\n    {\n      in = new Scanner( new FileReader(file) );\n      while (!found &amp;&amp; in.hasNextLine())\n      {\n        String line = in.nextLine();\n        if (line.contains(m_keyword))\n          found = true;\n      }  \n    }\n    catch (IOException ioe)\n    {\n      \/\/ Do nothing (results in found being returned false)\n    }\n    finally\n    {\n      if (in != null)\n        in.close();\n    }\n    return found;\n  }\n  \n  \/\/\/\/\/\/\/\/ Private data \/\/\/\/\/\/\/\/\/\/\n  private File m_directory;\n  private String m_keyword;\n  private int m_count;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">When this program was run on my NetBeans Threads project&#8217;s <strong>src<\/strong> directory, specifying &#8216;thread&#8217; as the keyword to search for, it produced the following output:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>26 files contained 'thread'<\/strong><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Executor_Framework\"><\/span>The Executor Framework<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">So far, we have created our threads by hand.&nbsp; However, it is common for applications to need a potentially large number of threads, and managing all those threads efficiently is not an easy task.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, it is now recommended that you use a set of interfaces and classes known as the&nbsp;<strong><em>Executor Framework<\/em><\/strong>&nbsp;to manage a group of threads known as a&nbsp;<strong><em>thread pool<\/em><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A particularly important part of this thread management is to provide support for&nbsp;<strong><em>&#8216;throttling&#8217;<\/em><\/strong>&nbsp;the number of concurrent threads.&nbsp; The idea is to provide a facility for limiting the number of threads and instead try to reuse those threads for the requested work.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>java.util.concurrent<\/strong><\/code>&nbsp;package provides a number of interfaces and classes designed for this purpose.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Executor_Interface\"><\/span>The Executor Interface<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">A class that implements the&nbsp;<code><strong>Executor<\/strong><\/code>&nbsp;interface is an object that executes submitted&nbsp;<code>Runnable<\/code>&nbsp;tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An Executor object is designed to replace the standard approach to starting a thread with its own style.&nbsp; If&nbsp;<code><strong>r<\/strong><\/code>&nbsp;is a&nbsp;<code><strong>Runnable<\/strong><\/code>&nbsp;object, and&nbsp;<code><strong>e<\/strong><\/code>&nbsp;is an <code><strong>Executor<\/strong><\/code> object you can replace<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>(new Thread(r)).start();\n<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>e.execute(r);\n<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is the single method that the&nbsp;<code><strong>Executor<\/strong><\/code>&nbsp;interface specifies:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>void execute(Runnable&nbsp;command)<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the&nbsp;<strong>Executor<\/strong>&nbsp;implementation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Parameters:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code><strong>command<\/strong><\/code>&nbsp;&#8211; the runnable task<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Throws:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code><strong>RejectedExecutionException<\/strong><\/code>&nbsp;&#8211; if this task cannot be accepted for execution.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code><strong>NullPointerException<\/strong><\/code>&nbsp;&#8211; if command is null<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"ScheduledExecutorService\"><\/span>ScheduledExecutorService<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>ScheduledExecutorService<\/strong><\/code>&nbsp;interface supplements the methods of its parent <code><strong>ExecutorService<\/strong><\/code> with <code><strong>schedule<\/strong><\/code>, which executes a <code><strong>Runnable<\/strong><\/code> or <code><strong>Callable<\/strong><\/code> task after a specified delay. In addition, the interface defines <code><strong>scheduleAtFixedRate<\/strong><\/code> and <code><strong>scheduleWithFixedDelay<\/strong><\/code>, which executes specified tasks repeatedly, at defined intervals.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">More details may be found&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/docs.oracle.com\/javase\/6\/docs\/api\/java\/util\/concurrent\/ScheduledExecutorService.html\" target=\"_blank\">here<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Executors_Class\"><\/span>The Executors Class<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>Executors<\/strong><\/code>&nbsp;class provides factory and utility methods for&nbsp;<code><strong>Executor<\/strong><\/code>,&nbsp;<code><strong>ExecutorService<\/strong><\/code>,&nbsp;<code><strong>ScheduledExecutorService<\/strong><\/code>,&nbsp;<code><strong>ThreadFactory<\/strong><\/code>, and&nbsp;<code><strong>Callable<\/strong><\/code>&nbsp;classes<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each of the thread pool factory methods returns a thread pool with particular characteristics:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>static&nbsp;ExecutorService<\/code><\/td><td><code><strong>newCachedThreadPool<\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.<\/td><\/tr><tr><td><code>static&nbsp;ExecutorService<\/code><\/td><td><code><strong>newCachedThreadPool<\/strong>(ThreadFactory&nbsp;threadFactory)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available, and uses the provided ThreadFactory to create new threads when needed.<\/td><\/tr><tr><td><code>static&nbsp;ExecutorService<\/code><\/td><td><code><strong>newFixedThreadPool<\/strong>(int&nbsp;nThreads)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue.<\/td><\/tr><tr><td><code>static&nbsp;ExecutorService<\/code><\/td><td><code><strong>newFixedThreadPool<\/strong>(int&nbsp;nThreads, ThreadFactory&nbsp;threadFactory)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue, using the provided ThreadFactory to create new threads when needed.<\/td><\/tr><tr><td><code>static&nbsp;ScheduledExecutorService<\/code><\/td><td><code><strong>newScheduledThreadPool<\/strong>(int&nbsp;corePoolSize)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.<\/td><\/tr><tr><td><code>static&nbsp;ScheduledExecutorService<\/code><\/td><td><code><strong>newScheduledThreadPool<\/strong>(int&nbsp;corePoolSize, ThreadFactory&nbsp;threadFactory)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>static&nbsp;ExecutorService<\/code><\/td><td><code><strong>newSingleThreadExecutor<\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates an Executor that uses a single worker thread operating off an unbounded queue.<\/td><\/tr><tr><td><code>static&nbsp;ExecutorService<\/code><\/td><td><code><strong>newSingleThreadExecutor<\/strong>(ThreadFactory&nbsp;threadFactory)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates an Executor that uses a single worker thread operating off an unbounded queue, and uses the provided ThreadFactory to create a new thread when needed.<\/td><\/tr><tr><td><code>static&nbsp;ScheduledExecutorService<\/code><\/td><td><code><strong>newSingleThreadScheduledExecutor<\/strong>()<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a single-threaded executor that can schedule commands to run after a given delay, or to execute periodically.<\/td><\/tr><tr><td><code>static&nbsp;ScheduledExecutorService<\/code><\/td><td><code><strong>newSingleThreadScheduledExecutor<\/strong>(ThreadFactory&nbsp;threadFactory)<\/code><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a single-threaded executor that can schedule commands to run after a given delay, or to execute periodically.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"An_Example-7\"><\/span>An Example<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of the use of these interfaces and classes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ve changed the previous&nbsp;<code><strong>MatchCounter<\/strong><\/code>&nbsp;example to use these features, and called it&nbsp;<code><strong>MatchCounterPoolDemo<\/strong><\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [11,12,13,15,35,54,55,56,57,65,67,102,103,104,105,169]; title: ; quick-code: false; notranslate\" title=\"\">\npackage threads;\n\nimport java.io.File;\nimport java.io.FileFilter;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Scanner;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.ThreadPoolExecutor;\n\n\/**\n * A class to represent a Callable value that returns the count\n * of files in a directory and its subdirectories that contain\n * a specified keyword.\n *\/\npublic class MatchCounterPoolDemo implements Callable&lt;Integer&gt;\n{\n  \/**\n   * Main entry point\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    Scanner in = new Scanner(System.in);\n    System.out.print(&quot;Starting directory? &quot;);\n    String directory = in.nextLine();\n    System.out.print(&quot;Keyword? &quot;);\n    String keyword = in.nextLine();\n    \n    ExecutorService pool = Executors.newCachedThreadPool();\n    \n    MatchCounterPoolDemo counter = \n                    new MatchCounterPoolDemo(new File(directory), keyword, pool);\n    Future&lt;Integer&gt; result = pool.submit(counter);\n\n    try\n    {\n      System.out.println( result.get() + &quot; files contained &#039;&quot; + keyword + &quot;&#039;&quot;);\n    }\n    catch (ExecutionException ee)\n    {\n      ee.printStackTrace();\n    }\n    catch (InterruptedException ie)\n    {\n      System.err.println(&quot;Execution interrupted&quot;);\n    }\n    \n    pool.shutdown();\n    \n    int largestPoolSize = ((ThreadPoolExecutor) pool).getLargestPoolSize();\n    System.out.println(&quot;Largest pool size: &quot; + largestPoolSize);\n  }\n  \n  \/**\n   * Creates a new instance of MatchCounterPoolDemo.\n   *\n   * @param directory the directory in which to start the search\n   * @param keyword the keyword to search for.\n   * @param pool the thread pool to use.\n   *\/\n  public MatchCounterPoolDemo(File directory, String keyword, ExecutorService pool)\n  {\n    m_directory = directory;\n    m_keyword = keyword;\n    m_pool = pool;\n  }\n\n  \/**\n   * Implements the required Callable method\n   *\/\n  public Integer call()\n  {\n    m_count = 0;\n    try\n    {\n      \/\/ Get list of files in current directory that match the file filter\n      File&#x5B;] files = m_directory.listFiles( new FileFilter()\n        {\n          public boolean accept(File file)\n          {\n            return file.isDirectory() || file.getName().endsWith(&quot;.java&quot;);\n          }\n        }\n      );\n      \n      \/\/ Create a results array\n      ArrayList&lt;Future&lt;Integer&gt;&gt; results = new ArrayList&lt;Future&lt;Integer&gt;&gt;();\n      \n      \/\/ Go through the files, doing a recursive and multi-threaded search.\n      for (File file : files)\n      {\n        if (file.isDirectory())\n        {\n          \/\/ Use another MatchCounterPoolDemo and another thread to search\n          \/\/ this directory.\n          MatchCounterPoolDemo counter = \n                            new MatchCounterPoolDemo(file, m_keyword, m_pool);\n          Future&lt;Integer&gt; result = m_pool.submit(counter);\n          results.add(result);\n        }\n        else\n        {\n          if (search(file))\n            m_count++;\n        }\n      }\n      \n      \/\/ Go through the Future results and accumulate the counts\n      for (Future&lt;Integer&gt; result : results)\n      {\n        try\n        {\n          m_count += result.get(); \/\/ Blocks until result available\n        }\n        catch (ExecutionException ee)\n        {\n          ee.printStackTrace();\n        }\n      }\n    }\n    catch (InterruptedException ie)\n    {\n      \/\/ Ignore\n    }\n    return m_count;\n  }\n\n  \/**\n   * Searches the specified file for a given keyword.\n   *\n   * @param file the file to search\n   * @return true if the keyword was found in the file.\n   *\/\n  private boolean search(File file)\n  {\n    Scanner in = null;\n    boolean found = false;\n    try\n    {\n      in = new Scanner( new FileReader(file) );\n      while (!found &amp;&amp; in.hasNextLine())\n      {\n        String line = in.nextLine();\n        if (line.contains(m_keyword))\n          found = true;\n      }  \n    }\n    catch (IOException ioe)\n    {\n      \/\/ Do nothing (results in found being returned false)\n    }\n    finally\n    {\n      if (in != null)\n        in.close();\n    }\n    return found;\n  }\n  \n  \/\/\/\/\/\/\/\/ Private data \/\/\/\/\/\/\/\/\/\/\n  private File m_directory;\n  private String m_keyword;\n  private ExecutorService m_pool;\n  private int m_count;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces, under similar conditions to the previous one:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>27 files contained 'thread'\nLargest pool size: 3<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">(I added one file since the last output.)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Synchronizers\"><\/span>Synchronizers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>java.util.concurrent<\/strong><\/code>&nbsp;package supports&nbsp;<strong><em>synchronizers<\/em><\/strong>, general purpose synchronization classes that facilitate coordination between threads.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These include:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Semaphore<\/strong>: A semaphore is a classic concurrency control construct. It is basically a lock with an attached counter. Similar to the&nbsp;<code><strong>Lock<\/strong><\/code>&nbsp;interface, it can be used to prevent access if the lock is granted. The&nbsp;<code><strong>Semaphore<\/strong><\/code>&nbsp;class keeps track of a set of permits. Each&nbsp;<code><strong>acquire()<\/strong><\/code>&nbsp;blocks if necessary until a permit is available, and then takes it. Each&nbsp;<code><strong>release()<\/strong><\/code>&nbsp;adds a permit. Note that no actual permit objects are used, the&nbsp;<code><strong>Semaphore<\/strong><\/code>&nbsp;maintains a count of the number available and acts accordingly. A semaphore with a counter of one can serve as a mutual exclusion lock.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Barrier<\/strong>: This is a synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. The interface to the barrier is the&nbsp;<code><strong>CyclicBarrier<\/strong><\/code>&nbsp;class, called cyclic because it can be re-used after the waiting threads are released. This is useful for parallel programming.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>CountDown Latch<\/strong>:A latch is a condition starting out false, but once set true remains true forever. The <strong>java.util.concurrent.CountDownLatch<\/strong> class serves as a synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. This synchronization tool is similar to a barrier in the sense that it provides methods that allow threads to wait for a condition, but the difference is that the release condition is not the number of threads that are waiting. Instead, the threads are released when the specified count reaches zero. The initial count is specified in the constructor; the latch does not reset and later attempts to lower the count will not work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Exchanger<\/strong>: Allows two threads to exchange objects at a rendezvous point, and can be useful in pipeline designs. Each thread presents some object on entry to the&nbsp;<code><strong>exchange()<\/strong><\/code>&nbsp;method and receives the object presented by the other thread on return. As an example, consider the classical consumer-producer problem (two entities share a channel); a description of the problem and a sample solution using built-in synchronization techniques (<code><strong>wait()<\/strong><\/code>&nbsp;and&nbsp;<code><strong>notify()<\/strong><\/code>) is discussed in the Java tutorial.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Threads &amp; Thread Groups What&#8217;s a ThreadGroup? Every&nbsp;Thread&nbsp;is a member of a&nbsp;ThreadGroup.&nbsp; A&nbsp;ThreadGroup&nbsp;provides a mechanism for a logical grouping of multiple threads and thread groups. It is possible to manipulate some of the attributes of all the threads in a thread group in a single call. The Default Thread Group If you create a thread [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":252,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_eb_attr":"","ocean_front_end_style_editor":"no","ocean_post_layout":"left-sidebar","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"ocs-course-topics-sidebar","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","footnotes":""},"class_list":["post-306","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/comments?post=306"}],"version-history":[{"count":35,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/306\/revisions"}],"predecessor-version":[{"id":389,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/306\/revisions\/389"}],"up":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/252"}],"wp:attachment":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/media?parent=306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}