Other methods of interest

Throughout the pages of this chapter, we have used some classes of the Java concurrency API to implement basic functionalities of the Executor framework. These classes also have other interesting methods. In this section, we explain some of them.

The Executors class provides other methods to create ThreadPoolExecutor objects. These methods are:

  • newCachedThreadPool(): This method creates a ThreadPoolExecutor object that reuses a worker-thread if it's idle, but it creates a new one if it's necessary. There is no maximum number of worker-threads.
  • newSingleThreadExecutor(): This method creates a ThreadPoolExecutor object that uses only a single worker-thread. The tasks you send to the executor are stored in a queue until the worker-thread can execute them.
  • The CountDownLatch class provides the following additional methods:
    • await(long timeout, TimeUnit unit): It waits till the internal counter arrives at zero to pass the time specified in the parameters. If the time passes, the method returns the false value.
    • getCount(): This method returns the actual value of the internal counter.

There are two types of concurrent data structures in Java:

  • Blocking data structures: When you call a method and the library can't do that operation (for example, you try to obtain an element, and the data structure is empty), they block the thread until the operation can be done.
  • Non-blocking data structures: When you call a method and the library can't do that operation (because the structure is empty or full), the method returns a special value or throws an exception.

There are data structures that implement both behaviors and data structures that implement only one. Usually, blocking data structures also implement the methods with non-blocking behavior, and non-blocking data structures don't implement the blocking methods.

The methods that implement the blocking operations are:

  • put(), putFirst(), putLast(): These insert an element in the data structure. If it's full, it blocks the thread until there is space.
  • take(), takeFirst(), takeLast(): These return and remove an element of the data structure. If it's empty, it blocks the thread until there is an element in it.

The methods that implement the non-blocking operations are:

  • add(), addFirst(), addLast(): These insert an element in the data structure. If it's full, the method throws an IllegalStateException exception.
  • remove(), removeFirst(), removeLast(): These return and remove an element from the data structure. If it's empty, the method throws an IllegalStateException exception.
  • element(), getFirst(), getLast(): These return but don't remove an element from the data structure. If it's empty, the method throws an IllegalStateException exception.
  • offer(), offerFirst(), offerLast(): These insert an element value in the data structure. If it's full, they return the false Boolean value.
  • poll(), pollFirst(), pollLast(): These return and remove an element from the data structure. If it's empty, they return the null value.
  • peek(), peekFirst(), peekLast(): These return but don't remove an element from the data structure. If it's empty, they return the null value.

In Chapter 11, Diving into Concurrent Data Structures and Synchronization Utilities, we will describe concurrent data structures in more detail.