Mastering Concurrency Programming with Java 9 - Second Edition
eBook - ePub

Mastering Concurrency Programming with Java 9 - Second Edition

Javier Fernandez Gonzalez

Share book
  1. 516 pages
  2. English
  3. ePUB (mobile friendly)
  4. Available on iOS & Android
eBook - ePub

Mastering Concurrency Programming with Java 9 - Second Edition

Javier Fernandez Gonzalez

Book details
Book preview
Table of contents
Citations

About This Book

Master the principles to make applications robust, scalable and responsiveAbout This Book• Implement concurrent applications using the Java 9 Concurrency API and its new components• Improve the performance of your applications and process more data at the same time, taking advantage of all of your resources• Construct real-world examples related to machine learning, data mining, natural language processing, and moreWho This Book Is ForThis book is for competent Java developers who have basic understanding of concurrency, but knowledge of effective implementation of concurrent programs or usage of streams for making processes more efficient is not requiredWhat You Will Learn• Master the principles that every concurrent application must follow• See how to parallelize a sequential algorithm to obtain better performance without data inconsistencies and deadlocks• Get the most from the Java Concurrency API components• Separate the thread management from the rest of the application with the Executor component• Execute phased-based tasks in an efficient way with the Phaser components• Solve problems using a parallelized version of the divide and conquer paradigm with the Fork / Join framework• Find out how to use parallel Streams and Reactive Streams• Implement the "map and reduce" and "map and collect" programming models• Control the concurrent data structures and synchronization mechanisms provided by the Java Concurrency API• Implement efficient solutions for some actual problems such as data mining, machine learning, and moreIn DetailConcurrency programming allows several large tasks to be divided into smaller sub-tasks, which are further processed as individual tasks that run in parallel. Java 9 includes a comprehensive API with lots of ready-to-use components for easily implementing powerful concurrency applications, but with high flexibility so you can adapt these components to your needs.The book starts with a full description of the design principles of concurrent applications and explains how to parallelize a sequential algorithm. You will then be introduced to Threads and Runnables, which are an integral part of Java 9's concurrency API. You will see how to use all the components of the Java concurrency API, from the basics to the most advanced techniques, and will implement them in powerful real-world concurrency applications.The book ends with a detailed description of the tools and techniques you can use to test a concurrent Java application, along with a brief insight into other concurrency mechanisms in JVM.Style and approachThis is a complete guide that implements real-world examples of algorithms related to machine learning, data mining, and natural language processing in client/server environments. All the examples are explained using a step-by-step approach.

Frequently asked questions

How do I cancel my subscription?
Simply head over to the account section in settings and click on “Cancel Subscription” - it’s as simple as that. After you cancel, your membership will stay active for the remainder of the time you’ve paid for. Learn more here.
Can/how do I download books?
At the moment all of our mobile-responsive ePub books are available to download via the app. Most of our PDFs are also available to download and we're working on making the final remaining ones downloadable now. Learn more here.
What is the difference between the pricing plans?
Both plans give you full access to the library and all of Perlego’s features. The only differences are the price and subscription period: With the annual plan you’ll save around 30% compared to 12 months on the monthly plan.
What is Perlego?
We are an online textbook subscription service, where you can get access to an entire online library for less than the price of a single book per month. With over 1 million books across 1000+ topics, we’ve got you covered! Learn more here.
Do you support text-to-speech?
Look out for the read-aloud symbol on your next book to see if you can listen to it. The read-aloud tool reads text aloud for you, highlighting the text as it is being read. You can pause it, speed it up and slow it down. Learn more here.
Is Mastering Concurrency Programming with Java 9 - Second Edition an online PDF/ePUB?
Yes, you can access Mastering Concurrency Programming with Java 9 - Second Edition by Javier Fernandez Gonzalez in PDF and/or ePUB format, as well as other popular books in Informatik & Programmierung in Java. We have over one million books available in our catalogue for you to explore.

Information

Year
2017
ISBN
9781785887451

Concurrency in JVM - Clojure and Groovy with the Gpars Library and Scala

Java is the most popular, but not the only programming language we can use to implement programs for the Java Virtual Machine (JVM). In the page https://en.wikipedia.org/wiki/List_of_JVM_languages you can find a list of all the programming languages you can use to implement programs for the JVM. Some of them are implementations of existing languages for the JVM, such as JRuby, which is an implementation of the Ruby programming language or Jython, which is an implementation of the Python programming language. Other languages follow different programming paradigms, such as Clojure, which is a functional programming language, and others are scripting and dynamic programming languages, such as Groovy. Most of them have good integration with the Java language; in fact you can use elements of Java directly in those programming languages, including concurrency elements such as Threads or Executors. Some of those languages implement their own concurrency models. In this chapter, we will undertake a fast introduction to the concurrency elements provided by three of those languages:
  • Clojure: Provides reference types such as Atom and Agent and other elements such as Future and Promise
  • Groovy: With the GPars library, provides elements for data parallelization, its own actor model, agents, and dataflow
  • Scala: Provides two elements, futures and promises

Concurrency in Clojure

Clojure is a dynamic, general-purpose functional programming language based on the Lisp programming language created by Rich Hickey. Via https://clojure.org/index, you can download the lastest version of the language (at the time of writing it is the 1.8.0 version) and find documentation and guides about how to program in the Clojure programming language. You can install support for Clojure in the most popular Java IDEs such as Eclipse. Another interesting web page is http://clojure-doc.org, where you can find the community-driven documentation site for the Clojure programming language.
In this section, we will show you the most important concurrency elements of the Clojure programming language and how to use them. We are not going to make an introduction to the Clojure programming language. You can review the commented webs to learn how to program in Clojure.
One of the design objectives of the Clojure programming language was to make concurrent programming easier. With this objective in mind, two important decisions were taken:
  • Clojure data structures are immutable, so they can be shared between threads without any problem. This does not mean that you can't have mutable values on concurrent applications as you'll see later.
  • Clojure separates the concepts of identity and value, almost deleting the need for explicit locks.
Let's describe and work with the most important concurrent structures provided by the Clojure programming language.

Using Java elements

You can use all the Java elements when you're programming in Clojure, including the concurrency ones, so you can create Threads or Executors or use the fork/join framework. This is not good practice, because Clojure makes easier concurrent programming, but you can explicitly create a Thread, as you can see in the following block of code:
 (ns example.example1) (defn example1 ( [number] (println (format "%s : %d"(Thread/currentThread) number)) )) (dotimes [i 10] (.start (Thread. (fn[] (example1 I))))) 
In this code, first, we define a function called example1 that receives a number as a parameter. Inside the function, we write information about the Thread that is executing the function and the number we have received as a parameter.
Then, we create and execute 10 Thread objects. Each thread will make a call to the function example1.
In the following screenshot, you can see the results of an execution of this code:
In the previous screenshot, you can see how the name of the Thread is different for all the 10 threads.

Reference types

As we mentioned before, Clojure data structures are immutable, but Clojure provides mechanisms that allow you to work with mutable variables using reference types. We can classify reference types as coordinated or uncoordinated and as synchronous or asynchronous:
  • Coordinated: When two or more operations cooperate with each other
  • Uncoordinated: When the operation doesn't affect other operations
  • Synchronous: When the caller waits for the finalization of the operation
  • Asynchronous: When the caller doesn't wait for the finalization of the operation
The most important reference types in the Clojure programming language are:
  • Atoms
  • Agents
  • Refs
Let's see in the following sections how to work with these elements.

Atoms

An atom is basically an atomic reference of the Java programming language. Changes in these kinds of variables are visible immediately to all the threads. We're going to use the following functions to work with atoms. They are an uncoordinated and synchronized reference type:
  • atom: To define a new atom object.
  • swap!: Atomically changes the value of the atom to a new one based on the result of a function. It follows the format (swap! atom function) where atom is the name of the atom object, and function is the function that returns the new value of the atom.
  • reset!: Establish the value of the atom to a new value. It follows the format (reset! atom value) where atom is the name of the atom object and value the new value.
  • compare-and-set!: Atomically changes the value of the atom if the actual value is the same as the value passed as a parameter. It follows the format (compare-and-set! atom old-value new-value) where atom is the name of the atom object, old-value is the expected actual value of the atom, and new value is the new value we want to assign to the atom.
Let's see an example of how to work with an atom object. First, we declare a function named company that receives two parameters named account and salary. Account will be an atom object, as you will see later, and salary will be a number. We use the swap! function to increment the value of the account object. Then, we write in the console information about the Thread that is executing the function and the actual value of the atom object using the @ (dereferencing) function:
 (ns example.example2) (defn company ( [account salary] (swap! account + salary) (println (format "%s : %d"(Thread/currentThread) @account)) )) 
Then, we create a similar function named user. It also receives the accountatom object as a parameter and another parameter named money. We also use the swap! function, but in this case, to decrease the value of the Atom object:
 (defn user ( [account money] (swap! account - money) (println (format "%s : %d"(Thread/currentThread) @account)) )) 
Then, we create a function named myTask that receives an atom object named account as a parameter and calls the company function 1000 times with the value 100 and the user function with the value 100, so the final value of the account object should be the same:
 (defn myTask ( [account] (dotimes [i 1000] (company account 100) (user account 100) (Thread/sleep 100) ))) 
Finally, we create the myAccount object as an atom object with the initial value of 0 and create 10 threads to execute the myTask function:
 (def myAccount (atom 0)) (dotimes [i 10] (.start (Thread. (fn[] (myTask myAccount))))) 
The following screenshot shows you an execution of this example:
In this image you can see how there are different threads running the myTask function and how the final value of the myAccount Atom is 0 as expected.

Agents

An Agent is a reference that is updated asynchronously, at some point in the future. It's associated with a single storage location throughout its life and you can only change the value of that location. Agents are an uncoordinated data structure.
You can use the following functions to work with agents:
  • agent: To create a new Agent object.
  • send: To establish the new value of the agent. It follows the syntax (send agent function value) where agent is the name of the agent we want to modify, function is a function to be executed to calculate the new value of the agent, and value is the value that will be passed to the function with the actual value of the agent to calculate the new one.
  • send-of: You can use this function when you want to use a function to update the value that is a blocking function (for example, reading a file). The send-of function will return immediately and the function that updates the value of the agent continues its execution in another thread. It follows the same syntax as the send function.
  • await: Waits (blocking the current thread) until all the pending operations with the agent have finished. If follows the syntax (await agent) where agent is the name of the agent we want to wait for.
  • await-for: You can use this function to wait the number of milliseconds specif...

Table of contents