{"id":43713,"date":"2015-09-16T19:32:23","date_gmt":"2015-09-16T16:32:23","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=43713"},"modified":"2023-12-13T11:50:47","modified_gmt":"2023-12-13T09:50:47","slug":"the-java-util-concurrent-package","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html","title":{"rendered":"The java.util.concurrent Package"},"content":{"rendered":"<p><em>This article is part of our Academy Course titled <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/java-concurrency-essentials.html\">Java Concurrency Essentials<\/a>.<\/em><\/p>\n<p><em><br \/>\n<\/em><em>In this course, you will dive into the magic of concurrency. You will be introduced to the fundamentals of concurrency and concurrent code and you will learn about concepts like atomicity, synchronization and thread safety. Check it out <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/java-concurrency-essentials.html\">here<\/a>!<\/em><\/p>\n<div class=\"toc\">\n<h4>Table Of Contents<\/h4>\n<dl>\n<dt><a href=\"#intro\">1. Introduction<\/a><\/dt>\n<dt><a href=\"#concurrent_package\">2. java.util.concurrent<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#executor\">2.1. Executor<\/a><\/dt>\n<dt><a href=\"#executor_service\">2.2. ExecutorService<\/a><\/dt>\n<dt><a href=\"#concurrent_collections\">2.3. Concurrent collections<\/a><\/dt>\n<dt><a href=\"#atomic_variables\">2.4. Atomic Variables<\/a><\/dt>\n<dt><a href=\"#semaphores\">2.5. Semaphore<\/a><\/dt>\n<dt><a href=\"#count_down_latch\">2.6. CountDownLatch<\/a><\/dt>\n<dt><a href=\"#cyclic_barrier\">2.7. CyclicBarrier<\/a><\/dt>\n<dl><\/dl>\n<\/dl>\n<\/dd>\n<dt><a href=\"#download\">3. Download the source code<\/a><\/dt>\n<\/dl>\n<\/div>\n<h2><a name=\"intro\"><\/a>1. Introduction<\/h2>\n<p>The following chapter introduces the <code>java.util.concurrent<\/code> package. Within this package reside a bunch of interesting classes that provide necessary and helpful functionality needed to implement multi-threaded applications. After a discussion on how to use the Executor interface and its implementation, the chapter covers atomic data types and concurrent data structures. The final section throws light at the semaphores and count-down latches.<\/p>\n<h2><a name=\"concurrent_package\"><\/a>2. java.util.concurrent<\/h2>\n<p>After having read the previous articles about <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/introduction-to-threads-and-concurrency\/\">concurrency<\/a> and <a href=\"\nhttps:\/\/www.javacodegeeks.com\/2015\/09\/concurrency-fundamentals-deadlocks-and-object-monitors\">multi-threading<\/a>, you might have the feeling that it is not always trivial to write robust code that executes well in a multi-threaded environment. There is a proverb that illustrates this (source unknown):<\/p>\n<ul>\n<li>Junior programmers think concurrency is hard.<\/li>\n<li>Experienced programmers think concurrency is easy.<\/li>\n<li>Senior programmers think concurrency is hard.<\/li>\n<\/ul>\n<p>Therefore a solid library of data structures and classes that provide well-tested thread-safety is of great help for anyone writing programs that make use of concurrency. Luckily the JDK provides a set of ready-to-use data structures and functionality for exactly that purpose. All these classes reside within the package java.util.concurrent.<\/p>\n<h3><a name=\"executor\"><\/a>2.1. Executor<\/h3>\n<p>The <code>java.util.concurrent<\/code> package defines a set of interfaces whose implementations execute tasks. The simplest one of these is the Executor interface:<\/p>\n<pre class=\"brush:java\">public interface Executor {\n\tvoid execute(Runnable command);\n}\n<\/pre>\n<p>Hence an Executor implementation takes the given Runnable instance and executes it. The interface makes no assumptions about the way of the execution, the javadoc only states &#8220;Executes the given command at some time in the future.&#8221;. A simple implementation could therefore be:<\/p>\n<pre class=\"brush:java\">public class MyExecutor implements Executor {\n\n\tpublic void execute(Runnable r) {\n\t\t(new Thread(r)).start();\n\t}\n}\n<\/pre>\n<p>Along with the mere interface the JDK also ships a fully-fledged and extendable implementation named <code>ThreadPoolExecutor<\/code>. Under the hood the <code>ThreadPoolExecutor<\/code> maintains a pool of threads and dispatches the instances of <code>Runnable<\/code> given the <code>execute()<\/code> method to the pool. The arguments passed to the constructor control the behavior of the thread pool. The constructor with the most arguments is the following one:<\/p>\n<p>ThreadPoolExecutor (int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue&lt;Runnable&gt; workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)<\/p>\n<p>Let&#8217;s go through the different arguments step by step:<\/p>\n<ul>\n<li><strong>corePoolSize<\/strong>: The <code>ThreadPoolExecutor<\/code> has an attribute <code>corePoolSize<\/code> that determines how many threads it will start until new threads are only started when the queue is full.<\/li>\n<li><strong>maximumPoolSize<\/strong>: This attribute determines how many threads are started at the maximum. You can set this to <code>Integer.MAX_VALUE<\/code> in order to have no upper boundary.<\/li>\n<li><strong>keepAliveTime<\/strong>: When the <code>ThreadPoolExecutor<\/code> has created more than <code>corePoolSize<\/code> threads, a thread will be removed from the pool when it idles for the given amount of time.<\/li>\n<li><strong>unit<\/strong>: This is just the <code>TimeUnit<\/code> for the <code>keepAliveTime<\/code>.<\/li>\n<li><strong>workQueue<\/strong>: This queue holds the instances of Runnable given through the <code>execute()<\/code> method until they are actually started.<\/li>\n<li><strong>threadFactory<\/strong>: An implementation of this interface gives you control over the creation of the threads used by the <code>ThreadPoolExecutor<\/code> .<\/li>\n<li><strong>handler<\/strong>: When you specify a fixed size for the workQueue and provide a maximumPoolSize then it may happen, that the <code>ThreadPoolExecutor<\/code> is not able to execute your <code>Runnable<\/code> instance due to saturation. In this case the provided handler is called and gives you control over what should happen in this case.<\/li>\n<\/ul>\n<p>As there are a lot of parameters to adjust, let&#8217;s examine some code that uses them:<\/p>\n<pre class=\"brush:java\">public class ThreadPoolExecutorExample implements Runnable {\n\tprivate static AtomicInteger counter = new AtomicInteger();\n\tprivate final int taskId;\n\n\tpublic int getTaskId() {\n\t\treturn taskId;\n\t}\n\n\tpublic ThreadPoolExecutorExample(int taskId) {\n\t\tthis.taskId = taskId;\n\t}\n\t\n\tpublic void run() {\n\t\ttry {\n\t\t\tThread.sleep(5000);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\n\tpublic static void main(String[] args) {\n\t\tBlockingQueue&lt;Runnable&gt; queue = new LinkedBlockingQueue&lt;Runnable&gt;(10);\n\t\tThreadFactory threadFactory = new ThreadFactory() {\n\t\t\tpublic Thread newThread(Runnable r) {\n\t\t\t\tint currentCount = counter.getAndIncrement();\n\t\t\t\tSystem.out.println(\"Creating new thread: \" + currentCount);\n\t\t\t\treturn new Thread(r, \"mythread\" + currentCount);\n\t\t\t}\n\t\t};\n\t\tRejectedExecutionHandler rejectedHandler = new RejectedExecutionHandler() {\n\t\t\tpublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {\n\t\t\t\tif (r instanceof ThreadPoolExecutorExample) {\n\t\t\t\t\tThreadPoolExecutorExample example = (ThreadPoolExecutorExample) r;\n\t\t\t\t\tSystem.out.println(\"Rejecting task with id \" + example.getTaskId());\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 1, TimeUnit.SECONDS, queue, threadFactory, rejectedHandler);\n\t\tfor (int i = 0; i &lt; 100; i++) {\n\t\t\texecutor.execute(new ThreadPoolExecutorExample(i));\n\t\t}\n\t\texecutor.shutdown();\n\t}\n}\n<\/pre>\n<p>Our <code>run()<\/code> implementation only falls asleep for 5 seconds, but this is not the main focus of this code. The <code>ThreadPoolExecutor<\/code> starts with 5 core threads and allows the pool to grow up to 10 threads at the maximum. For demonstration purposes we allow an unused thread only to idle for about 1 second. The queue implementation here is a <code>LinkedBlockingQueue<\/code> with a capacity of 10 <code>Runnable<\/code> instances. We also implement a simple <code>ThreadFactory<\/code> in order to track the thread creation. The same is true for the <code>RejectedExecutionHandler<\/code>.<\/p>\n<p>The loop in the <code>main()<\/code> method now issues 100 <code>Runnable<\/code> instance to the pool within a short amount of time. The output of the sample shows that we have to create 10 threads (up the maximum) to handle all pending <code>Runnables<\/code>:<\/p>\n<pre class=\"brush:bash\">Creating new thread: 0\n...\nCreating new thread: 9\nRejecting task with id 20\n...\nRejecting task with id 99\n<\/pre>\n<p>But it also shows that all tasks with taskId greater than 19 are forwarded to the <code>RejectedExecutionHandler<\/code>. This is due to the fact that our <code>Runnable<\/code> implementation sleeps for 5 seconds. After the first 10 threads have been started the queue can only hold another 10 <code>Runnable<\/code> instances. All further instances then have to be rejected.<\/p>\n<p>Finally the <code>shutdown()<\/code> method lets the <code>ThreadPoolExecutor<\/code> reject all further tasks and waits until the already issued tasks have been executed. You can replace the call of <code>shutdown()<\/code> with a call of <code>shutdownNow()<\/code>. The latter tries to interrupt all running threads and shuts down the thread pool without waiting for all threads to finish. In the example above you would see ten InterruptedException exceptions as our ten sleeping threads are woken up immediately.<\/p>\n<h3><a name=\"executor_service\"><\/a>2.2. ExecutorService<\/h3>\n<p>The <code>Executor<\/code> interface is very simple, it only forces the underlying implementation to implement the <code>execute()<\/code> method. The <code>ExecutorService<\/code> goes on step further as it extends the <code>Executor<\/code> interface and adds a series of utility methods (e.g. to add a complete collection of tasks), methods to shut down the thread pool as well as the ability to query the implementation for the result of the execution of one task. We have seen that the <code>Runnable<\/code> interface only defines a <code>run()<\/code> method is void as return value. Hence the introduction of a new interface named <code>Callable<\/code> was necessary that defines similar to <code>Runnable<\/code> also only one method, but this methods returns a value:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush:java\">V call();\n<\/pre>\n<p>But how does the JDK handle the fact that a task returns a value but is submitted to a thread pool for execution?<\/p>\n<p>The submitter of the task cannot know ahead when the task gets executed and how long the executions lasts. Letting the current thread wait for the result is obviously no solution. The work to check if the result is already available with the feature to block or to wait a certain amount of time is implemented in another class: <code>java.util.concurrent.Future&lt;V&gt;<\/code>. This class has only a few methods to check whether the task is done, to cancel the task as well as to retrieve its result.<\/p>\n<p>Last but not least we have another interface which extends the <code>Executor<\/code> interface as well as the <code>ExecutorService<\/code> interface by some methods to schedule a task at a given point in time. The name of the interface is <code>ScheduledExecutorService<\/code> and it provides basically a <code>schedule()<\/code> method that takes an argument how long to wait until the task gets executed:<\/p>\n<pre class=\"brush:java\">schedule(Callable&lt;V&gt; callable, long delay, TimeUnit unit);\nschedule(Runnable command, long delay, TimeUnit unit);\n<\/pre>\n<p>Like for the <code>ExecutorService<\/code> the <code>schedule()<\/code> method is available in two variants: One for the <code>Runnable<\/code> interface and one for tasks that return a value using the <code>Callable<\/code> interface. The <code>ScheduledExecutorService<\/code> also provides a method to execute tasks periodically:<\/p>\n<pre class=\"brush:java\">scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);\n<\/pre>\n<p>Next to the initial delay we can specify the period at which the task should run.<\/p>\n<p>The last example has already shown how to create a <code>ThreadPoolExecutor<\/code>. The implementation for the <code>ScheduledExecutorService<\/code> is named <code>ScheduledThreadPoolExecutor<\/code> and has to be handled very similar to the <code>ThreadPoolExecutor<\/code> used above. But often the full control over all features of an ExecutorService is not necessary. Just imagine a simple test client that should invoke some server methods using a simple <code>ThreadPool<\/code>.<\/p>\n<p>The creators of the JDK have therefore created a simple factory class named <code>Executors<\/code> (please mind the trailing s). This class provides a handful of static methods to create a read-to-use <code>ThreadPoolExecutor<\/code>. All of this together lets us implement a simple thread pool that executes a bunch of tasks that compute some number (the number crunching operation is here for demonstration purposes substituted by a simple <code>Thread.sleep()<\/code>):<\/p>\n<pre class=\"brush:java\">public class ExecutorsExample implements Callable&lt;Integer&gt; {\n\tprivate static Random random = new Random(System.currentTimeMillis());\n\n\tpublic Integer call() throws Exception {\n\t\tThread.sleep(1000);\n\t\treturn random.nextInt(100);\n\t}\n\n\tpublic static void main(String[] args) throws InterruptedException, ExecutionException {\n\t\tExecutorService executorService = Executors.newFixedThreadPool(5);\n\t\tFuture&lt;Integer&gt;[] futures = new Future[5];\n\t\tfor (int i = 0; i &lt; futures.length; i++) {\n\t\t\tfutures[i] = executorService.submit(new ExecutorsExample());\n\t\t}\n\t\tfor (int i = 0; i &lt; futures.length; i++) {\n\t\t\tInteger retVal = futures[i].get();\n\t\t\tSystem.out.println(retVal);\n\t\t}\n\t\texecutorService.shutdown();\n\t}\n}\n<\/pre>\n<p>The creation of the <code>ExecutorService<\/code> is a one-liner. To execute some tasks we just need a for-loop that creates a few new instances of ExecutorsExample and stores the returned Future in an array. After we have submitted the tasks to the service, we just wait for the result. The method <code>get()<\/code> of <code>Future<\/code> is blocking, i.e. the current threads sleeps until the result is available. An overridden version of this method takes a timeout specification in order to let the waiting thread proceed if the task does not finish within the defined time period.<\/p>\n<h3><a name=\"concurrent_collections\"><\/a>2.3. Concurrent collections<\/h3>\n<p>The Java collections framework encompasses a wide range of data structures that every Java programmers uses in his day to day work. This collection is extended by the data structures within the <code>java.util.concurrent<\/code> package. These implementations provided thread-safe collections to be used within a multi-threaded environment.<\/p>\n<p>Many Java programmers even use thread-safe data structures from time to time even without knowing that. The &#8220;old&#8221; classes <code>Hashtable<\/code> and <code>Vector<\/code> are examples for such classes. Being part of the JDK since version 1.0, these basic data structures were designed with thread-safety in mind. Although the thread-safety here only means that all methods are synchronized on instance level. The following code is taken from Oracle&#8217;s JDK implementation:<\/p>\n<pre class=\"brush:java\">public synchronized void clear() {\n\tEntry tab[] = table;\n\tmodCount++;\n\tfor (int index = tab.length; --index &gt;= 0; )\n\t\ttab[index] = null;\n\tcount = 0;\n}\n<\/pre>\n<p>This is crucial difference to the &#8220;newer&#8221; collection classes like <code>HashMap<\/code> or <code>ArrayList<\/code> (both available since JDK 1.2), which themselves are not thread-safe. But there is a convenient way to retrieve a thread-safe instance of such a &#8220;newer&#8221; collection class:<\/p>\n<pre class=\"brush:java\">HashMap&lt;Long,String&gt; map = new HashMap&lt;Long, String&gt;();\nMap&lt;Long, String&gt; synchronizedMap = Collections.synchronizedMap(map);\n<\/pre>\n<p>As we see in the code above, the <code>Collections<\/code> class lets us create at runtime a synchronized version of a formerly unsynchronized collections class.<\/p>\n<p>As we have learned before, adding the keyword synchronized to a method results in the effect that at each point in time only one thread executes a method of the object under investigation. This is of course the easiest way to make a simple collection class thread-safe. More advanced techniques encompass special algorithms that are designed for concurrent access. These algorithms are implemented in the collection classes of the <code>java.util.concurrent<\/code> package.<\/p>\n<p>An example for such a class is <code>ConcurrentHashMap<\/code>:<\/p>\n<pre class=\"brush:java\">ConcurrentHashMap&lt;Long,String&gt; map = new ConcurrentHashMap&lt;Long,String&gt;();\nmap.put(key, value);\nString value2 = map.get(key);\n<\/pre>\n<p>The code above looks nearly the same as for a normal <code>HashMap<\/code>, but the underlying implementation is completely different. Instead of using only one lock for the whole table the <code>ConcurrentHashMap<\/code> subdivides the whole table into many small partitions. Each partition has its own lock. Hence write operations to this map from different threads, assuming they are writing at different partitions of the table, do not compete and can use their own lock.<\/p>\n<p>The implementation also introduces the idea of a commit of write operations to reduce the waiting time for read operations. This slightly changes the semantics of the read operation as it will return the result of the latest write operation that has finished. This means that the number of entries may not be the same directly before and after executing the read method, like it would be when using a synchronized method, but for concurrent applications this is not always important. The same is true for the iterator implementation of the <code>ConcurrentHashMap<\/code>.<\/p>\n<p>To get a better feeling for the different performance of <code>Hashtable<\/code>, synchronized <code>HashMap<\/code> and <code>ConcurrentHashMap<\/code>, let&#8217;s implement a simple performance test. The following code starts a few threads and lets each thread retrieve a value from the map at a random position and afterwards updates a value at another random position:<\/p>\n<pre class=\"brush:java\">public class MapComparison implements Runnable {\n\tprivate static Map&lt;Integer, String&gt; map;\n\tprivate Random random = new Random(System.currentTimeMillis());\n\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\trunPerfTest(new Hashtable&lt;Integer, String&gt;());\n\t\trunPerfTest(Collections.synchronizedMap(new HashMap&lt;Integer,String&gt;()));\n\t\trunPerfTest(new ConcurrentHashMap&lt;Integer, String&gt;());\n\t\trunPerfTest(new ConcurrentSkipListMap&lt;Integer, String&gt;());\n\t}\n\n\tprivate static void runPerfTest(Map&lt;Integer, String&gt; map) throws InterruptedException {\n\t\tMapComparison.map = map;\n\t\tfillMap(map);\n\t\tExecutorService executorService = Executors.newFixedThreadPool(10);\n\t\tlong startMillis = System.currentTimeMillis();\n\t\tfor (int i = 0; i &lt; 10; i++) {\n\t\t\texecutorService.execute(new MapComparison());\n\t\t}\n\t\texecutorService.shutdown();\n\t\texecutorService.awaitTermination(1, TimeUnit.MINUTES);\n\t\tSystem.out.println(map.getClass().getSimpleName() + \" took \" + (System.currentTimeMillis() - startMillis) + \" ms\");\n\t}\n\n\tprivate static void fillMap(Map&lt;Integer, String&gt; map) {\n\t\tfor (int i = 0; i &lt; 100; i++) {\n\t\t\tmap.put(i, String.valueOf(i));\n\t\t}\n\t}\n\n\tpublic void run() {\n\t\tfor (int i = 0; i &lt; 100000; i++) {\n\t\t\tint randomInt = random.nextInt(100);\n\t\t\tmap.get(randomInt);\n\t\t\trandomInt = random.nextInt(100);\n\t\t\tmap.put(randomInt, String.valueOf(randomInt));\n\t\t}\n\t}\n}\n<\/pre>\n<p>The output of this program is the following:<\/p>\n<pre class=\"brush:bash\">Hashtable took 436 ms\nSynchronizedMap took 433 ms\nConcurrentHashMap took 75 ms\nConcurrentSkipListMap took 89 ms\n<\/pre>\n<p>As we have expected, the <code>Hashtable<\/code> and the synchronized <code>HashMap<\/code> implementations are far behind the ones from the concurrent package. This example also introduces a skip list implementation of the HashMap, where the linked items within one bucket form a skip list, meaning the list is sorted and there are different levels of linking the items within the list. The highest level pointer points directly to some item in the middle of the list. If this item is already greater than the current item, the iterator has to take the next lower level of linkage to skip fewer elements than on the highest level. A detailed description of skip lists can be found <a href=\"http:\/\/en.wikipedia.org\/wiki\/Skip_list\">here<\/a>. The interesting point about skip list is that all read access takes about log(n) time, even if all items are stored within the same bucket.<br \/>\n[ulp id=&#8217;DdINgEqoOovgkhhk-3&#8242;]<br \/>\n&nbsp;<\/p>\n<h3><a name=\"atomic_variables\"><\/a>2.4. Atomic Variables<\/h3>\n<p>When having multiple threads sharing a single variable, we have the task to synchronize access to this variable. The reason for this is the fact, that even a simple instruction like i++ is not atomic. It basically consists of the following bytecode instructions:<\/p>\n<pre class=\"brush:java\">iload_1       \niinc 1, 1\nistore_1\n<\/pre>\n<p>Without knowing too much about the Java bytecode, one sees that the current value of the local variable 1 is pushed onto the operand stack, that it is incremented by the constant value 1 and afterwards popped from the stack and stored in the local variable number one. This means we need three atomic operations in order to increment a local variable by one. In a multi-threading environment this also means that the scheduler can stop the execution of the current thread between each of these instructions and start a new thread, which in turn then can work on the same variable.<\/p>\n<p>To cope with situations like this you can of course synchronize the access to this specific variable:<\/p>\n<pre class=\"brush:java\">synchronized(i) {\n\ti++;\n}\n<\/pre>\n<p>But this also means the current thread has to acquire the lock on i which needs some internal synchronization and computation within the JVM. This approach is also called pessimistic locking as we assume that it is highly probable that another thread currently holds the lock we want to acquire. A different approach called optimistic locking, assumes that there are not so many threads competing for the resource and hence we just try to update the value and see if this has worked. One implementation of this approach is the compare-and-swap (CAS) method. This operation is implemented on many modern CPUs as atomic operation. It compares the content of a given memory location with a given value (the &#8220;expected value&#8221;) and updates it to a new value if the current value equals to the expected value. In pseudo code this looks like:<\/p>\n<pre class=\"brush:java\">int currentValue = getValueAtMemoryPosition(pos);\nif(currentValue == expectedValue) {\n\tsetValueAtMemoryPosition(pos, newValue);\n}\n<\/pre>\n<p>The CAS operation implements the code above as one atomic operation. Therefore it can be used to see if the value of some variable has still the value the current thread holds and updates it to the incremented value in this case. As the usage of the CAS operation needs hardware support, the JDK provides special classes to support these operations. They all reside within the package java.util.concurrent.atomic.<\/p>\n<p>One representative of these classes is <a href=\"http:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/concurrent\/atomic\/AtomicInteger.html\">java.util.concurrent.atomic.AtomicInteger<\/a>. The CAS operation discussed above is implemented by the method<\/p>\n<pre class=\"brush:java\">\tboolean compareAndSet(int expect, int update)\n<\/pre>\n<p>The boolean return value indicates if the update operation was successful or not. On the basis of this functionality further operation like an atomic increment operation can be implemented (here taken from Oracle&#8217; JDK implementation):<\/p>\n<pre class=\"brush:java\">    public final int getAndIncrement() {\n        for (;;) {\n            int current = get();\n            int next = current + 1;\n            if (compareAndSet(current, next))\n                return current;\n        }\n    }\n<\/pre>\n<p>Now we are able to increment an integer variable by different threads without using pessimistic locks:<\/p>\n<pre class=\"brush:java\">public class AtomicIntegerExample implements Runnable {\n\tprivate static final AtomicInteger atomicInteger = new AtomicInteger();\n\n\tpublic static void main(String[] args) {\n\t\tExecutorService executorService = Executors.newFixedThreadPool(5);\n\t\tfor (int i = 0; i &lt; 5; i++) {\n\t\t\texecutorService.execute(new AtomicIntegerExample());\n\t\t}\n\t\texecutorService.shutdown();\n\t}\n\n\tpublic void run() {\n\t\tfor (int i = 0; i &lt; 10; i++) {\n\t\t\tint newValue = atomicInteger.getAndIncrement();\n\t\t\tif (newValue == 42) {\n\t\t\t\tSystem.out.println(\"[\" + Thread.currentThread().getName() + \"]: \" + newValue);\n\t\t\t}\n\t\t}\n\t}\n}\n<\/pre>\n<p>The code above starts five threads and lets each of them increment the <code>AtomicInteger<\/code> variable. The lucky thread that gets the answer 42 prints this to the console. When executing this example code in repetition, the output will only be created by exactly one thread.<\/p>\n<p>Next to <code>AtomicInteger<\/code> the JDK also offers classes for atomic operations on long values, integer and long arrays and references.<\/p>\n<h3><a name=\"semaphores\"><\/a>2.5. Semaphore<\/h3>\n<p>Semaphores are used to control access to a shared resource. In contrast to simple synchronized blocks a semaphore has an internal counter that is increased each time a thread acquires a lock and decreased each time a thread releases a lock it obtained before. The increasing and decreasing operations are of course synchronized, hence a semaphore can be used to control how many threads pass simultaneously through a critical section. The two basic operations of a thread are:<\/p>\n<pre class=\"brush:java\">void acquire();\nvoid release();\n<\/pre>\n<p>The constructor takes next to the number of concurrently locks a fairness parameter. The fairness parameter decides if new threads, which try to acquire a lock, are set at the beginning or at the end of the list of waiting threads. Putting the new thread at the end of the threads guarantees that all threads will acquire the lock after some time and hence no thread starves.<\/p>\n<pre class=\"brush:java\">Semaphore(int permits, boolean fair)\n<\/pre>\n<p>To illustrate the described behavior, let&#8217;s setup a simple thread pool with five threads but control through a semaphore that at each point in time not more than three of them are running:<\/p>\n<pre class=\"brush:java\">public class SemaphoreExample implements Runnable {\n\tprivate static final Semaphore semaphore = new Semaphore(3, true);\n\tprivate static final AtomicInteger counter = new AtomicInteger();\n\tprivate static final long endMillis = System.currentTimeMillis() + 10000;\n\n\tpublic static void main(String[] args) {\n\t\tExecutorService executorService = Executors.newFixedThreadPool(5);\n\t\tfor (int i = 0; i &lt; 5; i++) {\n\t\t\texecutorService.execute(new SemaphoreExample());\n\t\t}\n\t\texecutorService.shutdown();\n\t}\n\n\tpublic void run() {\n\t\twhile(System.currentTimeMillis() &lt; endMillis) {\n\t\t\ttry {\n\t\t\t\tsemaphore.acquire();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\tSystem.out.println(\"[\"+Thread.currentThread().getName()+\"] Interrupted in acquire().\");\n\t\t\t}\n\t\t\tint counterValue = counter.incrementAndGet();\n\t\t\tSystem.out.println(\"[\"+Thread.currentThread().getName()+\"] semaphore acquired: \"+counterValue);\n\t\t\tif(counterValue &gt; 3) {\n\t\t\t\tthrow new IllegalStateException(\"More than three threads acquired the lock.\");\n\t\t\t}\n\t\t\tcounter.decrementAndGet();\n\t\t\tsemaphore.release();\n\t\t}\n\t}\n}\n<\/pre>\n<p>The Semaphore is constructed by passing 3 as the number of concurrent permits. When trying to acquire a lock, the blocked thread may experience an <code>InterruptedException<\/code> that has to be caught. Alternatively one could also call the utility method <code>acquireUninterruptibly()<\/code> to circumvent the try-catch construct.<\/p>\n<p>To ensure that we have not more than three concurrent threads within the critical section, we use an <code>AtomicInteger<\/code> that gets incremented each time a process enters the section and decremented before it leaves the section. When the counter has a value higher than four, an <code>IllegalStateException<\/code> is thrown. Finally we <code>release()<\/code> the semaphore and let another waiting thread enter the critical section.<\/p>\n<h3><a name=\"count_down_latch\"><\/a>2.6. CountDownLatch<\/h3>\n<p>The <code>CountDownLatch<\/code> class is another helpful class for thread synchronization from the JDK. Similar to the <code>Semaphore<\/code> class it provides a counter, but the counter of the <code>CountDownLatch<\/code> can only be decreased until it reaches zero. Once the counter has reached zero all threads waiting on the <code>CountDownLatch<\/code> can proceed. Such functionality is often necessary when all threads of a pool have to synchronize at some point in order to proceed. A simple example would be an application that has to gather data from different sources before being able to store a new data set to the database.<\/p>\n<p>The following code demonstrates how five threads sleep for a random amount of time. Each thread which wakes up counts down the latch and then awaits the latch to become zero. Finally all threads output that they have finished.<\/p>\n<pre class=\"brush:java\">public class CountDownLatchExample implements Runnable {\n\tprivate static final int NUMBER_OF_THREADS = 5;\n\tprivate static final CountDownLatch latch = new CountDownLatch(NUMBER_OF_THREADS);\n\tprivate static Random random = new Random(System.currentTimeMillis());\n\n\tpublic static void main(String[] args) {\n\t\tExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS);\n\t\tfor (int i = 0; i &lt; NUMBER_OF_THREADS; i++) {\n\t\t\texecutorService.execute(new CountDownLatchExample());\n\t\t}\n\t\texecutorService.shutdown();\n\t}\n\n\tpublic void run() {\n\t\ttry {\n\t\t\tint randomSleepTime = random.nextInt(20000);\n\t\t\tSystem.out.println(\"[\" + Thread.currentThread().getName() + \"] Sleeping for \" + randomSleepTime);\n\t\t\tThread.sleep(randomSleepTime);\n\t\t\tlatch.countDown();\n\t\t\tSystem.out.println(\"[\" + Thread.currentThread().getName() + \"] Waiting for latch.\");\n\t\t\tlatch.await();\n\t\t\tSystem.out.println(\"[\" + Thread.currentThread().getName() + \"] Finished.\");\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}\n<\/pre>\n<p>When running this example you will see that the output &#8220;Waiting for latch.&#8221; comes at different points in time but that the &#8220;Finished.&#8221; message of each thread is printed immediately one after the other.<\/p>\n<h3><a name=\"cyclic_barrier\"><\/a>2.7. CyclicBarrier<\/h3>\n<p>In contrast to the <code>CountDownLatch<\/code>, the <code>CyclicBarrier<\/code> class implements a counter that can be reset after being counted down to zero. All threads have to call its method <code>await()<\/code> until the internal counter is set to zero. The waiting threads are then woken up and can proceed. Internally the counter is then reset to its original value and the whole procedure can start again:<\/p>\n<pre class=\"brush:java\">public class CyclicBarrierExample implements Runnable {\n\tprivate static final int NUMBER_OF_THREADS = 5;\n\tprivate static AtomicInteger counter = new AtomicInteger();\n\tprivate static Random random = new Random(System.currentTimeMillis());\n\tprivate static final CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {\n\t\tpublic void run() {\n\t\t\tcounter.incrementAndGet();\n\t\t}\n\t});\n\n\tpublic static void main(String[] args) {\n\t\tExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS);\n\t\tfor (int i = 0; i &lt; NUMBER_OF_THREADS; i++) {\n\t\t\texecutorService.execute(new CyclicBarrierExample());\n\t\t}\n\t\texecutorService.shutdown();\n\t}\n\n\tpublic void run() {\n\t\ttry {\n\t\t\twhile(counter.get() &lt; 3) {\n\t\t\t\tint randomSleepTime = random.nextInt(10000);\n\t\t\t\tSystem.out.println(\"[\" + Thread.currentThread().getName() + \"] Sleeping for \" + randomSleepTime);\n\t\t\t\tThread.sleep(randomSleepTime);\n\t\t\t\tSystem.out.println(\"[\" + Thread.currentThread().getName() + \"] Waiting for barrier.\");\n\t\t\t\tbarrier.await();\n\t\t\t\tSystem.out.println(\"[\" + Thread.currentThread().getName() + \"] Finished.\");\n\t\t\t}\n\t\t} catch (Exception e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}\n<\/pre>\n<p>The example above is very similar to the <code>CountDownLatch<\/code>, but in contrast to the previous example, I have added a while loop to the <code>run()<\/code> method. This <code>run()<\/code> implementations lets each thread continue the sleeping and <code>await()<\/code> procedure until the counter is three. Also note the anonymous Runnable() implementation provided to the constructor of <code>CyclicBarrier<\/code>. Its <code>run()<\/code> method gets executed each time the barrier is tripped. Here we increase the counter that is checked by the concurrent threads.<\/p>\n<h2><a name=\"download\"><\/a>3. Download the source code<\/h2>\n<p>You can download the source code of this lesson: <a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/concurrency-4.zip\">concurrency-4.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article is part of our Academy Course titled Java Concurrency Essentials. In this course, you will dive into the magic of concurrency. You will be introduced to the fundamentals of concurrency and concurrent code and you will learn about concepts like atomicity, synchronization and thread safety. Check it out here! Table Of Contents 1. &hellip;<\/p>\n","protected":false},"author":506,"featured_media":148,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[88,121,380],"class_list":["post-43713","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-java","tag-concurrency","tag-performance-and-scalability","tag-threads"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The java.util.concurrent Package - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"This article is part of our Academy Course titled Java Concurrency Essentials. In this course, you will dive into the magic of concurrency. You will be\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The java.util.concurrent Package - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"This article is part of our Academy Course titled Java Concurrency Essentials. In this course, you will dive into the magic of concurrency. You will be\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-16T16:32:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-13T09:50:47+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Martin Mois\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Martin Mois\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html\"},\"author\":{\"name\":\"Martin Mois\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/52c1e27ea19337c20d53df5286590760\"},\"headline\":\"The java.util.concurrent Package\",\"datePublished\":\"2015-09-16T16:32:23+00:00\",\"dateModified\":\"2023-12-13T09:50:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html\"},\"wordCount\":3062,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"keywords\":[\"Concurrency\",\"Performance and Scalability\",\"Threads\"],\"articleSection\":[\"Core Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html\",\"name\":\"The java.util.concurrent Package - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"datePublished\":\"2015-09-16T16:32:23+00:00\",\"dateModified\":\"2023-12-13T09:50:47+00:00\",\"description\":\"This article is part of our Academy Course titled Java Concurrency Essentials. In this course, you will dive into the magic of concurrency. You will be\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/the-java-util-concurrent-package.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Core Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/core-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"The java.util.concurrent Package\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/52c1e27ea19337c20d53df5286590760\",\"name\":\"Martin Mois\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g\",\"caption\":\"Martin Mois\"},\"description\":\"Martin is a Java EE enthusiast and works for an international operating company. He is interested in clean code and the software craftsmanship approach. He also strongly believes in automated testing and continuous integration.\",\"sameAs\":[\"http:\\\/\\\/martinsdeveloperworld.wordpress.com\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/martin-mois\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The java.util.concurrent Package - Java Code Geeks","description":"This article is part of our Academy Course titled Java Concurrency Essentials. In this course, you will dive into the magic of concurrency. You will be","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html","og_locale":"en_US","og_type":"article","og_title":"The java.util.concurrent Package - Java Code Geeks","og_description":"This article is part of our Academy Course titled Java Concurrency Essentials. In this course, you will dive into the magic of concurrency. You will be","og_url":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2015-09-16T16:32:23+00:00","article_modified_time":"2023-12-13T09:50:47+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","type":"image\/jpeg"}],"author":"Martin Mois","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Martin Mois","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html"},"author":{"name":"Martin Mois","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/52c1e27ea19337c20d53df5286590760"},"headline":"The java.util.concurrent Package","datePublished":"2015-09-16T16:32:23+00:00","dateModified":"2023-12-13T09:50:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html"},"wordCount":3062,"commentCount":4,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","keywords":["Concurrency","Performance and Scalability","Threads"],"articleSection":["Core Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html","url":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html","name":"The java.util.concurrent Package - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","datePublished":"2015-09-16T16:32:23+00:00","dateModified":"2023-12-13T09:50:47+00:00","description":"This article is part of our Academy Course titled Java Concurrency Essentials. In this course, you will dive into the magic of concurrency. You will be","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/the-java-util-concurrent-package.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Core Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/core-java"},{"@type":"ListItem","position":4,"name":"The java.util.concurrent Package"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/52c1e27ea19337c20d53df5286590760","name":"Martin Mois","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/051a80ba18f758940b686c6c4bb4b5f02d59abe8cc42a95b3545f7565c7a40a1?s=96&d=mm&r=g","caption":"Martin Mois"},"description":"Martin is a Java EE enthusiast and works for an international operating company. He is interested in clean code and the software craftsmanship approach. He also strongly believes in automated testing and continuous integration.","sameAs":["http:\/\/martinsdeveloperworld.wordpress.com\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/martin-mois"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/43713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/506"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=43713"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/43713\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/148"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=43713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=43713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=43713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}