Java 9 Concurrency Cookbook, Second Edition - Javier Fernández González - E-Book

Java 9 Concurrency Cookbook, Second Edition E-Book

Javier Fernandez Gonzalez

0,0
39,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Writing concurrent and parallel programming applications is an integral skill for any Java programmer. Java 9 comes with a host of fantastic features, including significant performance improvements and new APIs.
This book will take you through all the new APIs, showing you how to build parallel and multi-threaded applications. The book covers all the elements of the Java Concurrency API, with essential recipes that will help you take advantage of the exciting new capabilities.
You will learn how to use parallel and reactive streams to process massive data sets. Next, you will move on to create streams and use all their intermediate and terminal operations to process big collections of data in a parallel and functional way.
Further, you’ll discover a whole range of recipes for almost everything, such as thread management, synchronization, executors, parallel and reactive streams, and many more. At the end of the book, you will learn how to obtain information about the status of some of the most useful components of the Java Concurrency API and how to test concurrent applications using different tools.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 626

Veröffentlichungsjahr: 2017

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Title Page

Java 9 Concurrency Cookbook

Second Edition

Master the art of fast, effective Java development with the power of concurrent and parallel programming
Javier Fernández González

BIRMINGHAM - MUMBAI

Copyright

Java 9 Concurrency Cookbook

Second Edition

Copyright © 2017 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

First published: October 2012

Second edition: April 2017

Production reference: 1170417

Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B32PB, UK.

ISBN 978-1-78712-441-7

www.packtpub.com

Credits

Author

Javier Fernández González

Copy Editor

Gladson Monteiro

Reviewer

Piotr Bzdyl

Project Coordinator

Vaidehi Sawant

Commissioning Editor

Kunal Parikh

Proofreader

Safis Editing

Acquisition Editor

Denim Pinto

Indexer

Tejal Daruwale Soni

C

ontent

De

velopment

Editor

Nikhil Borkar

Graphics

Abhinash Sahu

Technical Editor

Subhalaxmi Nadar

Production Coordinator

Melwyn Dsa

About the Author

Javier Fernández González is a software architect with almost 15 years of experience in Java technologies. He has worked as a teacher, researcher, programmer, analyst, and writer, and he now works as an architect in all types of projects related to Java, especially J2EE. As a teacher, has taken over 1,000 hours of training in basic Java, J2EE, and the Struts framework. As a researcher, he has worked in the field of information retrieval, developing applications for processing large amounts of data in Java, and has participated as a coauthor in several journal articles and conference presentations. Recently, he worked on developing J2EE web applications for various clients from different sectors (public administration, insurance, healthcare, transportation, and so on). Currently, he works as a software architect. He is the author of the book, Java 7 Concurrency Cookbook and Mastering Concurrency Programming with Java 8 by Packt.

About the Reviewer

Piotr Bzdyl is focused on Java concurrency topics, including other JVM languages and their libraries, aimed at helping in creating highly concurrent applications (async IO, non-blocking APIs, Scala, Akka, and Clojure). He has been helping teams with JVM tuning and troubleshooting.

He has also created a training course for Java concurrency topics, covering core JDK multithreading concepts as well as those from external libraries and languages (actors, STM, parallel collections, and functional languages).

You can connect with Piotr on LinkedIn at https://www.linkedin.com/in/piotrbzdyl and on GitHub at https://github.com/pbzdyl. You can follow him on Stack Overflow at http://stackoverflow.com/cv/piotrekbzdyl.

www.PacktPub.com

For support files and downloads related to your book, please visit www.PacktPub.com.

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.comand as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.

https://www.packtpub.com/mapt

Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.

Why subscribe?

Fully searchable across every book published by Packt

Copy and paste, print, and bookmark content

On demand and accessible via a web browser

Customer Feedback

Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at https://www.amazon.com/dp/178712441X.

If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!

Dedication

To Nuria, Paula, and Pelayo, for you infinite love and patience

Table of Contents

Preface

What this book covers

What you need for this book

Who this book is for

Sections

Getting ready

How to do it…

How it works…

There's more…

See also

Conventions

Reader feedback

Customer support

Downloading the example code

Errata

Piracy

Questions

Thread Management

Introduction

Creating, running, and setting the characteristics of a thread

Getting ready

How to do it...

How it works...

There's more...

See also

Interrupting a thread

Getting ready

How to do it...

How it works...

There's more...

Controlling the interruption of a thread

Getting ready

How to do it...

How it works...

There's more...

See also

Sleeping and resuming a thread

Getting ready

How to do it...

How it works...

There's more...

Waiting for the finalization of a thread

Getting ready

How to do it...

How it works...

There's more...

Creating and running a daemon thread

Getting ready

How to do it...

How it works...

There's more...

Processing uncontrolled exceptions in a thread

Getting ready

How to do it...

How it works...

There's more...

See also

Using thread local variables

Getting ready

How to do it...

How it works...

There's more...

Grouping threads and processing uncontrolled exceptions in a group of threads

Getting ready

How to do it...

How it works...

See also

Creating threads through a factory

Getting ready

How to do it...

How it works...

See also

Basic Thread Synchronization

Introduction

Synchronizing a method

Getting ready

How to do it...

How it works...

There's more...

See also

Using conditions in synchronized code

Getting ready

How to do it...

How it works...

There's more...

See also

Synchronizing a block of code with a lock

Getting ready

How to do it...

How it works...

There's more...

Avoiding deadlocks

See also

Synchronizing data access with read/write locks

Getting ready...

How to do it...

How it works...

See also

Using multiple conditions in a lock

Getting ready

How to do it...

How it works...

There's more...

See also

Advanced locking with the StampedLock class

Getting ready

How to do it...

How it works...

There's more...

See also

Thread Synchronization Utilities

Introduction

Controlling concurrent access to one or more copies of a resource

Getting ready

How to do it...

How it works...

There's more...

Fairness in semaphores

See also

Waiting for multiple concurrent events

Getting ready

How to do it...

How it works...

There's more...

Synchronizing tasks in a common point

Getting ready

How to do it...

How it works...

There's more...

Resetting a CyclicBarrier object

Broken CyclicBarrier objects

See also

Running concurrent-phased tasks

Getting ready

How to do it...

How it works...

There's more...

Registering participants in Phaser

Forcing the termination of Phaser

See also

Controlling phase change in concurrent-phased tasks

Getting ready

How to do it...

How it works...

See also

Exchanging data between concurrent tasks

Getting ready

How to do it...

How it works...

There's more...

Completing and linking tasks asynchronously

Getting ready

How to do it...

How it works...

There's more...

See also...

Thread Executors

Introduction

Creating a thread executor and controlling its rejected tasks

Getting ready

How to do it...

How it works...

There's more...

See also

Executing tasks in an executor that returns a result

Getting ready

How to do it...

How it works...

There's more...

See also

Running multiple tasks and processing the first result

Getting ready

How to do it...

How it works...

There's more...

See also

Running multiple tasks and processing all the results

Getting ready

How to do it...

How it works...

There's more...

See also

Running a task in an executor after a delay

Getting ready

How to do it...

How it works...

There's more...

See also

Running a task in an executor periodically

Getting ready

How to do it...

How it works...

There's more...

See also

Canceling a task in an executor

Getting ready

How to do it...

How it works...

There's more...

See also

Controlling a task finishing in an executor

Getting ready

How to do it...

How it works...

See also

Separating the launching of tasks and the processing of their results in an executor

Getting ready

How to do it...

How it works...

There's more...

See also

Fork/Join Framework

Introduction

Creating a fork/join pool

Getting ready

How to do it...

How it works...

There's more...

See also

Joining the results of the tasks

How to do it...

How it works...

There's more...

See also

Running tasks asynchronously

How to do it...

How it works...

There's more...

See also

Throwing exceptions in the tasks

Getting ready

How to do it...

How it works...

There's more...

See also

Canceling a task

Getting ready...

How to do it...

How it works...

See also

Parallel and Reactive Streams

Introduction

Creating streams from different sources

Getting ready

How to do it...

How it works...

There's more...

See also

Reducing the elements of a stream

Getting ready

How to do it...

How it works...

There's more...

See also

Collecting the elements of a stream

Getting ready

How to do it...

How it works...

There's more...

See also

Applying an action to every element of a stream

Getting ready

How to do it...

How it works...

There's more...

See also

Filtering the elements of a stream

Getting ready

How to do it...

How it works...

There's more...

See also

Transforming the elements of a stream

Getting ready

How to do it...

How it works...

There's more...

See also

Sorting the elements of a stream

Getting ready

How to do it...

How it works...

There's more...

See also

Verifying conditions in the elements of a stream

Getting ready

How to do it...

How it works...

There's more...

See also

Reactive programming with reactive streams

Getting ready

How to do it...

How it works...

There's more...

Concurrent Collections

Introduction

Using non-blocking thread-safe deques

Getting ready

How to do it...

How it works...

There's more...

Using blocking thread-safe deques

Getting ready

How to do it...

How it works...

There's more...

See also

Using blocking thread-safe queue ordered by priority

Getting ready

How to do it...

How it works...

There's more...

See also

Using thread-safe lists with delayed elements

Getting ready

How to do it...

How it works...

There's more...

See also

Using thread-safe navigable maps

Getting ready

How to do it...

How it works...

There's more...

See also

Using thread-safe HashMaps

Getting ready

How to do it...

How it works...

There's more...

See also

Using atomic variables

Getting ready

How to do it...

How it works...

There's more...

See also

Using atomic arrays

Getting ready

How to do it...

How it works...

There's more...

See also

Using the volatile keyword

Getting ready

How to do it...

How it works...

There's more...

See also

Using variable handles

Getting ready

How to do it...

How it works...

There's more...

See also

Customizing Concurrency Classes

Introduction

Customizing the ThreadPoolExecutor class

Getting ready

How to do it...

How it works...

See also

Implementing a priority-based Executor class

Getting ready

How to do it...

How it works...

There's more...

See also

Implementing the ThreadFactory interface to generate custom threads

Getting ready

How to do it...

How it works...

There's more...

Using our ThreadFactory in an Executor object

Getting ready

How to do it...

How it works...

See also

Customizing tasks running in a scheduled thread pool

Getting ready

How to do it...

How it works...

There's more...

See also

Implementing the ThreadFactory interface to generate custom threads for the fork/join framework

Getting ready

How to do it...

How it works...

There's more...

See also

Customizing tasks running in the fork/join framework

How to do it...

How it works...

See also

Implementing a custom Lock class

Getting ready

How to do it...

How it works...

There's more...

See also

Implementing a transfer queue-based on priorities

Getting ready

How to do it...

How it works...

See also

Implementing your own atomic object

Getting ready

How to do it...

How it works...

See also

Implementing your own stream generator

Getting ready

How to do it...

How it works...

There's more...

See also

Implementing your own asynchronous stream

Getting ready

How to do it...

How it works...

There's more...

See also

Testing Concurrent Applications

Introduction

Monitoring a Lock interface

Getting ready

How to do it...

How it works...

There's more...

See also

Monitoring a Phaser class

Getting ready

How to do it...

How it works...

See also

Monitoring an Executor framework

Getting ready

How to do it...

How it works...

See also

Monitoring a fork/join pool

Getting ready

How to do it...

How it works...

See also

Monitoring a stream

Getting ready

How to do it...

How it works...

See also

Writing effective log messages

Getting ready

How to do it...

How it works...

There's more...

See also

Analyzing concurrent code with FindBugs

Getting ready

How to do it...

How it works...

There's more...

See also

Configuring Eclipse for debugging concurrency code

Getting ready

How to do it...

How it works...

Configuring NetBeans for debugging concurrency code

Getting ready

How to do it...

How it works...

There's more...

See also

Testing concurrency code with MultithreadedTC

Getting ready

How to do it...

How it works...

There's more...

See also

Monitoring with JConsole

Getting ready

How to do it...

How it works...

There's more...

See also

Additional Information

Introduction

Processing results for Runnable objects in the Executor framework

Getting ready

How to do it...

How it works...

There's more...

See also

Processing uncontrolled exceptions in a ForkJoinPool class

How to do it...

How it works...

There's more...

See also

Using a blocking thread-safe queue for communicating with producers and consumers

Getting ready

How to do it...

How it works...

There's more...

See also

Monitoring a Thread class

Getting ready

How to do it...

How it works...

There's more...

See also

Monitoring a Semaphore class

Getting ready

How to do it...

How it works...

See also

Generating concurrent random numbers

Getting ready

How to do it...

How it works...

There's more...

See also

Concurrent Programming Design

Introduction

Using immutable objects when possible

Getting ready

How to do it...

How it works...

There's more...

See also

Avoiding deadlocks by ordering locks

How to do it...

How it works...

There's more...

See also

Using atomic variables instead of synchronization

Getting ready

How to do it...

How it works...

See also

Holding locks for as short time as possible

Getting ready

How to do it...

How it works...

See also

Delegating the management of threads to executors

Getting ready

How to do it...

How it works...

See also

Using concurrent data structures instead of programming yourself

There's more...

See also

Taking precautions using lazy initialization

Getting ready

How to do it...

How it works...

Using the fork/join framework instead of executors

Getting ready

How to do it...

How it works...

See also

Avoiding the use of blocking operations inside a lock

Getting ready

How to do it...

How it works...

See also

Avoiding the use of deprecated methods

Using executors instead of thread groups

See also

Using streams to process big data sets

Getting ready

How to do it...

How it works...

See also

Other tips and tricks

See also

Preface

When you work with a computer, you can do several things at once. You can listen to music while you edit a document in a word processor and read your e-mails. This can be done because your operating system allows the concurrency of tasks. Concurrent programming is about the elements and mechanisms a platform offers to have multiple tasks or programs running at once and communicating with each other, to exchange data or to synchronize with each other. Java is a concurrent platform, and it offers a lot of classes to execute concurrent tasks inside a Java program. With each version, Java increases the functionalities offered to programmers to facilitate the development of concurrent programs. This book covers the most important and useful mechanisms included in version 9 of the Java concurrency API, so you will be able to use them directly in your applications. The mechanisms are as follows:

Basic thread management

Thread synchronization mechanisms

Thread creation and management delegation with executors

Fork/Join framework to enhance the performance of your application

Parallel streams to process big sets of data in a parallel way, including the new Java 9 reactive streams

Data structures for concurrent programs

Adapting the default behavior of some concurrency classes to your needs

Testing Java concurrency applications

What this book covers

Chapter 1, Thread Management, teaches you how to make basic operations with threads. The creation, execution, and status management of threads are explained through basic examples.

Chapter 2, Basic Thread Synchronization, covers how to use low-level Java mechanisms to synchronize code. Locks and the synchronized keyword are explained in detail.

Chapter 3, Thread Synchronization Utilities, teaches how to use the high-level utilities of Java to manage the synchronization between threads in Java. It includes an explanation of how to use the Phaser class to synchronize tasks divided into phases.

Chapter 4, Thread Executors, explores the delegation of thread management to executors. They allow running, managing, and getting the results of concurrent tasks.

Chapter 5, Fork/Join Framework, covers the use of the Fork/Join framework. It’s a special kind of executor oriented to execute tasks that will be divided into smaller ones using the divide and conquer technique.

Chapter 6, Parallel and Reactive Streams, teaches you how to create streams and use all its intermediate and terminal operations to process big collections of data in a parallel and functional way. Streams were introduced in Java 8. Java 9 has included some new interfaces to implement reactive streams.

Chapter 7, Concurrent Collections, explains how to use some concurrent data structures provided by the Java language. These data structures must be used in concurrent programs to avoid the use of synchronized blocks of code in their implementation.

Chapter 8, Customizing Concurrency Classes, teaches you how to adapt some of the most useful classes of the Java concurrency API to your needs.

Chapter 9, Testing Concurrent Applications, covers how to obtain information about the status of some of the most useful structures of the Java 7 concurrency API. You will also learn how to use some free tools to debug concurrent applications, such as the Eclipse, NetBeans IDE, or FindBugs applications to detect possible bugs in your applications.

Chapter 10, Additional Information, explores the notions of synchronization, the executor, the Fork/Join framework, concurrent data structures, and the monitoring of concurrent objects, which were not included in the respective chapters.

Chapter 11, Concurrent Programming Design, provides some tips that every programmer should consider when they develop a concurrent application.

What you need for this book

To follow this book, you need some basic knowledge of the Java programming language. You should know how to use an IDE, such as Eclipse or NetBeans, but this is not a necessary prerequisite.

Who this book is for

If you are a Java developer interested in enhancing your knowledge of concurrent programming and multithreading further, as well as discovering the new concurrency features of Java 8 and Java 9, then the Java 9 Concurrency Cookbook is for you. You should already be comfortable with general Java development practices, and a basic grasp of threads would be an advantage.

Sections

In this book, you will find several headings that appear frequently (Getting ready, How to do it, How it works, There's more, and See also).

To give clear instructions on how to complete a recipe, we use these sections as follows:

Getting ready

This section tells you what to expect in the recipe, and describes how to set up any software or any preliminary settings required for the recipe.

How to do it…

This section contains the steps required to follow the recipe.

How it works…

This section usually consists of a detailed explanation of what happened in the previous section.

There's more…

This section consists of additional information about the recipe in order to make the reader more knowledgeable about the recipe.

See also

This section provides helpful links to other useful information for the recipe.

Conventions

In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.

Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "The one that executes the main() method."

A block of code is set as follows:

Thread task=new PrimeGenerator(); task.start();

New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: "Create a new project by clicking on theNew Projectoption under theFilemenu"

Warnings or important notes appear in a box like this.
Tips and tricks appear like this.

Reader feedback

Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of.

To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message.

If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors .

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.

Downloading the example code

You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

You can download the code files by following these steps:

Log in or register to our website using your e-mail address and password.

Hover the mouse pointer on the

SUPPORT

tab at the top.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box.

Select the book for which you're looking to download the code files.

Choose from the drop-down menu where you purchased this book from.

Click on

Code Download

.

You can also download the code files by clicking on the Code Files button on the book's webpage at the Packt Publishing website. This page can be accessed by entering the book's name in the Search box. Please note that you need to be logged in to your Packt account.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR / 7-Zip for Windows

Zipeg / iZip / UnRarX for Mac

7-Zip / PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Java-9-Concurrency-Cookbook-Second-Edition. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.

To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.

Piracy

Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.

Please contact us at [email protected] with a link to the suspected pirated material.

We appreciate your help in protecting our authors and our ability to bring you valuable content.

Questions

If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.

Thread Management

In this chapter, we will cover the following topics:

Creating, running, and setting the characteristics of a thread

Interrupting a thread

Controlling the interruption of a thread

Sleeping and resuming a thread

Waiting for the finalization of a thread

Creating and running a daemon thread

Processing uncontrolled exceptions in a thread

Using thread local variables

Grouping threads and processing uncontrolled exceptions in a group of threads

Creating threads through a factory

Introduction

In the computer world, when we talk about concurrency, we refer to a series of independent and unrelated tasks that run simultaneously on a computer. This simultaneity can be real if the computer has more than one processor or a multi-core processor, or it can be apparent if the computer has only one core processor.

All modern operating systems allow the execution of concurrent tasks. You can read your e-mails while listening to music or reading news on a web page. We can say this is process-level concurrency. But inside a process, we can also have various simultaneous tasks. Concurrent tasks that run inside a process are called threads. Another concept related to concurrency is parallelism. There are different definitions and relations with the concurrency concept. Some authors talk about concurrency when you execute your application with multiple threads in a single-core processor. With this, you can see when your program execution is apparent. They talk about parallelism when you execute your application with multiple threads in a multi-core processor or in a computer with more than one processor, so this case is real as well. Other authors talk about concurrency when the threads of an application are executed without a predefined order, and they discuss parallelism when all these threads are executed in an ordered way.

This chapter presents a number of recipes that will show you how to perform basic operations with threads, using the Java 9 API. You will see how to create and run threads in a Java program, how to control their execution, process exceptions thrown by them, and how to group some threads to manipulate them as a unit.

Creating, running, and setting the characteristics of a thread

In this recipe, we will learn how to do basic operations over a thread using the Java API. As with every element in the Java language, threads are objects. We have two ways of creating a thread in Java:

Extending the

Thread

class and overriding the

run()

method.

Building a class that implements the

Runnable

interface and the

run()

method and then creating an object of the

Thread

class by passing the

Runnable

object as a parameter--this is the preferred approach and it gives you more flexibility.

In this recipe, we will use the second approach to create threads. Then, we will learn how to change some attributes of the threads. The Thread class saves some information attributes that can help us identify a thread, know its status, or control its priority. These attributes are:

ID

: This attribute stores a unique identifier for each thread.

Name

: This attribute stores the name of the thread.

Priority

: This attribute stores the priority of the

Thread

objects. In Java 9, threads can have priority between 1 and 10, where 1 is the lowest priority and 10 is the highest. It's not recommended that you change the priority of the threads. It's only a hint to the underlying operating system and it doesn't guarantee anything, but it's a possibility that you can use if you want.

Status

: This attribute stores the status of a thread. In Java, a thread can be present in one of the six states defined in the

Thread.State

enumeration:

NEW

,

RUNNABLE

,

BLOCKED

,

WAITING

,

TIMED_WAITING

, or

TERMINATED

. The following is a list specifying what each of these states means:

NEW

: The thread has been created and it has not yet started

RUNNABLE

: The thread is being executed in the JVM

BLOCKED

: The thread is blocked and it is waiting for a monitor

WAITING

: The thread is waiting for another thread

TIMED_WAITING

: The thread is waiting for another thread with a specified waiting time

TERMINATED

: The thread has finished its execution

In this recipe, we will implement an example that will create and run 10 threads that would calculate the prime numbers within the first 20,000 numbers.

Getting ready

The example for this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.

How it works...

The following screenshot shows the console part of the output of the program. We can see that all the threads we have created run in parallel to do their respective jobs:

In this screenshot, you can see how threads are created and how the ones with an even number are executed first, as they have the highest priority, and the others executed later, as they have minimum priority. The following screenshot shows part of the output of the log.txt file where we write information about the status of the threads:

Every Java program has at least one execution thread. When you run the program, JVM runs the execution thread that calls the main() method of the program.

When we call the start() method of a Thread object, we are creating another execution thread. Our program will have as many execution threads as the number of calls made to the start() method.

The Thread class has attributes to store all of the information of a thread. The OS scheduler uses the priority of threads to select the one that uses the CPU at each moment and actualizes the status of every thread according to its situation.

If you don't specify a name for a thread, JVM automatically assigns it one in this format: Thread-XX, where XX is a number. You can't modify the ID or status of a thread. The Thread class doesn't implement the setId() and setStatus() methods as these methods introduce modifications in the code.

A Java program ends when all its threads finish (more specifically, when all its non-daemon threads finish). If the initial thread (the one that executes the main() method) ends, the rest of the threads will continue with their execution until they finish. If one of the threads uses the System.exit() instruction to end the execution of the program, all the threads will end their respective execution.

Creating an object of the Thread class doesn't create a new execution thread. Also, calling the run() method of a class that implements the Runnable interface doesn't create a new execution thread. Only when you call the start() method, a new execution thread is created.

There's more...

As mentioned in the introduction of this recipe, there is another way of creating a new execution thread. You can implement a class that extends the Thread class and overrides the run() method of this class. Then, you can create an object of this class and call the start() method to have a new execution thread.

You can use the static method currentThread() of the Thread class to access the thread object that is running the current object.

You have to take into account that the setPriority() method can throw an IllegalArgumentException exception if you try to establish priority that isn't between 1 and 10.

See also

The

Creating threads through a factory

recipe of this chapter

Interrupting a thread

A Java program with more than one execution thread only finishes when the execution of all of its threads end (more specifically, when all its non-daemon threads end their execution or when one of the threads uses the System.exit() method). Sometimes, you may need to finish a thread because you want to terminate a program or when a user of the program wants to cancel the tasks that a thread object is doing.

Java provides an interruption mechanism that indicates to a thread that you want to finish it. One peculiarity of this mechanism is that thread objects have to check whether they have been interrupted or not, and they can decide whether they respond to the finalization request or not. A thread object can ignore it and continue with its execution.

In this recipe, we will develop a program that creates a thread and forces its finalization after 5 seconds, using the interruption mechanism.

Getting ready

The example for this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.

How to do it...

Follow these steps to implement the example:

Create a class called

PrimeGenerator

that extends the

Thread

class:

public class PrimeGenerator extends Thread{

Override the

run()

method including a loop that will run indefinitely. In this loop, process consecutive numbers beginning from one. For each number, calculate whether it's a prime number; if yes, as in this case, write it to the console:

@Override public void run() { long number=1L; while (true) { if (isPrime(number)) { System.out.printf("Number %d is Prime\n",number); }

After processing a number, check whether the thread has been interrupted by calling the

isInterrupted()

method. If this method returns

true

, the thread has been interrupted. In this case, we write a message in the console and end the execution of the thread:

if (isInterrupted()) { System.out.printf("The Prime Generator has been Interrupted"); return; } number++; } }

Implement the

isPrime()

method. You can get its code from the

Creating, running, and setting information of a thread

recipe of this chapter.

Now implement the main class of the example by implementing a class called

Main

and the

main()

method:

public class Main { public static void main(String[] args) {

Create and start an object of the

PrimeGenerator

class:

Thread task=new PrimeGenerator(); task.start();

Wait for 5 seconds and interrupt the

PrimeGenerator

thread:

try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } task.interrupt();

Then, write information related to the status of the interrupted thread. The output of this piece of code will depend on whether the thread ends its execution before or after:

System.out.printf("Main: Status of the Thread: %s\n", task.getState()); System.out.printf("Main: isInterrupted: %s\n", task.isInterrupted()); System.out.printf("Main: isAlive: %s\n", task.isAlive()); }

Run the example and see the results.

How it works...

The following screenshot shows the result of the execution of the previous example. We can see how the PrimeGenerator thread writes the message and ends its execution when it detects that it has been interrupted. Refer to the following screenshot:

The Thread class has an attribute that stores a boolean value indicating whether the thread has been interrupted or not. When you call the interrupt() method of a thread, you set that attribute to true. The isInterrupted() method only returns the value of that attribute.

The main() method writes information about the status of the interrupted thread. In this case, as this code is executed before the thread has finished its execution, the status is RUNNABLE, the return value of the isInterrupted() method is true, and the return value of the isAlive() method is true as well. If the interrupted Thread finishes its execution before the execution of this block of code (you can, for example, sleep the main thread for a second), the methods isInterrupted() and isAlive() will return a false value.

There's more...

The Thread class has another method to check whether a thread has been interrupted or not. It's the static method, interrupted(), that checks whether the current thread has been interrupted or not.

There is an important difference between the isInterrupted() and interrupted() methods. The first one doesn't change the value of the interrupted attribute, but the second one sets it to false.

As mentioned earlier, a thread object can ignore its interruption, but this is not the expected behavior.

Controlling the interruption of a thread

In the previous recipe, you learned how you can interrupt the execution of a thread and what you have to do to control this interruption in the thread object. The mechanism shown in the previous example can be used if the thread that can be interrupted is simple. But if the thread implements a complex algorithm divided into some methods or it has methods with recursive calls, we will need to use a better mechanism to control the interruption of the thread. Java provides the InterruptedException exception for this purpose. You can throw this exception when you detect the interruption of a thread and catch it in the run() method.

In this recipe, we will implement a task that will look for files with a determined name in a folder and in all its subfolders. This is to show how you can use the InterruptedException exception to control the interruption of a thread.

Getting ready

The example for this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.

How it works...

The following screenshot shows the result of an execution of this example. You can see how the FileSearch object ends its execution when it detects that it has been interrupted.

In this example, we use Java exceptions to control the interruption of a thread. When you run the example, the program starts going through folders by checking whether they have the file or not. For example, if you enter in the \b\c\d folder, the program will have three recursive calls to the directoryProcess() method. When it detects that it has been interrupted, it throws an InterruptedException exception and continues the execution in the run() method, no matter how many recursive calls have been made.

There's more...

The InterruptedException exception is thrown by some Java methods related to a concurrency API, such as sleep(). In this case, this exception is thrown if the thread is interrupted (with the interrupt() method) when it's sleeping.

See also

The

Interrupting a thread

recipe of this chapter

Sleeping and resuming a thread

Sometimes, you may be interested in pausing the execution of a thread during a determined period of time. For example, a thread in a program checks the sensor state once per minute. The rest of the time, it does nothing. During this time, the thread doesn't use any resources of the computer. After this period is over, the thread will be ready to continue with its execution when the operating system scheduler chooses it to be executed. You can use the sleep() method of the Thread class for this purpose. This method receives a long number as a parameter that indicates the number of milliseconds during which the thread will suspend its execution. After that time, the thread continues with its execution in the next instruction to the sleep() one when the JVM assigns it CPU time.

Another possibility is to use the sleep() method of an element of the TimeUnit enumeration. This method uses the sleep() method of the Thread class to put the current thread to sleep, but it receives the parameter in the unit that it represents and converts it into milliseconds.

In this recipe, we will develop a program that uses the sleep() method to write the actual date every second.

Getting ready

The example for this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.

How it works...

When you run the example, you would see how the program writes a Date object per second and also the message indicating that the FileClock thread has been interrupted.

When you call the sleep() method, the thread leaves the CPU and stops its execution for a period of time. During this time, it's not consuming CPU time, so the CPU could be executing other tasks.

When the thread is sleeping and is interrupted, the method throws an InterruptedException exception immediately and doesn't wait until the sleeping time is finished.

There's more...

The Java concurrency API has another method that makes a thread object leave the CPU. It's the yield() method, which indicates to the JVM that the thread object can leave the CPU for other tasks. The JVM does not guarantee that it will comply with this request. Normally, it's only used for debugging purposes.

Waiting for the finalization of a thread

In some situations, we will have to wait for the end of the execution of a thread (the run() method ends its execution). For example, we may have a program that will begin initializing the resources it needs before proceeding with the rest of the execution. We can run initialization tasks as threads and wait for their finalization before continuing with the rest of the program.

For this purpose, we can use the join() method of the Thread class. When we call this method using a thread object, it suspends the execution of the calling thread until the object that is called finishes its execution.

In this recipe, we will learn the use of this method with an initialization example.

Getting ready

The example for this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.

How it works...

When you run this program, you would understand how both the thread objects start their execution. First, the DataSourcesLoader thread finishes its execution. Then, the NetworkConnectionsLoader class finishes its execution. At this moment, the main thread object continues its execution and writes the final message.

There's more...

Java provides two additional forms of the join() method:

join (long milliseconds)

join (long milliseconds, long nanos)

In the first version of the join() method, instead of indefinitely waiting for the finalization of the thread called, the calling thread waits for the milliseconds specified as the parameter of the method. For example, if the object thread1 has thread2.join(1000), thread1 suspends its execution until one of these two conditions are met:

thread2

has finished its execution

1,000 milliseconds have passed

When one of these two conditions is true, the join() method returns. You can check the status of the thread to know whether the join() method was returned because it finished its execution or because the specified time had passed.

The second version of the join() method is similar to the first one, but it receives the number of milliseconds and nanoseconds as parameters.

Creating and running a daemon thread

Java has a special kind of thread called daemon thread. When daemon threads are the only threads running in a program, the JVM ends the program after finishing these threads.

With these characteristics, daemon threads are normally used as service providers for normal (also called user) threads running in the same program. They usually have an infinite loop that waits for the service request or performs the tasks of a thread. A typical example of these kinds of threads is the Java garbage collector.

In this recipe, we will learn how to create a daemon thread by developing an example with two threads: one user thread that would write events on a queue and a daemon thread that would clean the queue, removing the events that were generated more than 10 seconds ago.

Getting ready

The example for this recipe has been implemented using the Eclipse IDE. If you use Eclipse or a different IDE, such as NetBeans, open it and create a new Java project.