Effective Java

Joshua Bloch

Mentioned 20

A new edition of this title is available, ISBN-10: 0321356683 ISBN-13: 9780321356680

More on Amazon.com

Mentioned in questions and answers.

What issues / pitfalls must be considered when overriding equals and hashCode?

For an inheritance-friendly implementation, check out Tal Cohen's solution, How Do I Correctly Implement the equals() Method?


In his book Effective Java Programming Language Guide (Addison-Wesley, 2001), Joshua Bloch claims that "There is simply no way to extend an instantiable class and add an aspect while preserving the equals contract." Tal disagrees.

His solution is to implement equals() by calling another nonsymmetric blindlyEquals() both ways. blindlyEquals() is overridden by subclasses, equals() is inherited, and never overridden.


class Point {
    private int x;
    private int y;
    protected boolean blindlyEquals(Object o) {
        if (!(o instanceof Point))
            return false;
        Point p = (Point)o;
        return (p.x == this.x && p.y == this.y);
    public boolean equals(Object o) {
        return (this.blindlyEquals(o) && o.blindlyEquals(this));

class ColorPoint extends Point {
    private Color c;
    protected boolean blindlyEquals(Object o) {
        if (!(o instanceof ColorPoint))
            return false;
        ColorPoint cp = (ColorPoint)o;
        return (super.blindlyEquals(cp) && 
        cp.color == this.color);

Note that equals() must work across inheritance hierarchies if the Liskov Substitution Principle is to be satisfied.

Let's say you have a class called Customer, which contains the following fields:

  • UserName
  • Email
  • First Name
  • Last Name

Let's also say that according to your business logic, all Customer objects must have these four properties defined.

Now, we can do this pretty easily by forcing the constructor to specify each of these properties. But it's pretty easy to see how this can spiral out of control when you are forced to add more required fields to the Customer object.

I've seen classes that take in 20+ arguments into their constructor and it's just a pain to use them. But, alternatively, if you don't require these fields you run into the risk of having undefined information, or worse, object referencing errors if you rely on the calling code to specify these properties.

Are there any alternatives to this or do you you just have to decide whether X amount of constructor arguments is too many for you to live with?

In your case, stick with the constructor. The information belongs in Customer and 4 fields are fine.

In the case you have many required and optional fields the constructor is not the best solution. As @boojiboy said, it's hard to read and it's also hard to write client code.

@contagious suggested using the default pattern and setters for optional attributs. That mandates that the fields are mutable, but that's a minor problem.

Joshua Block on Effective Java 2 say that in this case you should consider a builder. An example taken from the book:

 public class NutritionFacts {  
   private final int servingSize;  
   private final int servings;  
   private final int calories;  
   private final int fat;  
   private final int sodium;  
   private final int carbohydrate;  

   public static class Builder {  
     // required parameters  
     private final int servingSize;  
     private final int servings;  

     // optional parameters  
     private int calories         = 0;  
     private int fat              = 0;  
     private int carbohydrate     = 0;  
     private int sodium           = 0;  

     public Builder(int servingSize, int servings) {  
      this.servingSize = servingSize;  
       this.servings = servings;  

     public Builder calories(int val)  
       { calories = val;       return this; }  
     public Builder fat(int val)  
       { fat = val;            return this; }  
     public Builder carbohydrate(int val)  
       { carbohydrate = val;   return this; }  
     public Builder sodium(int val)  
       { sodium = val;         return this; }  

     public NutritionFacts build() {  
       return new NutritionFacts(this);  

   private NutritionFacts(Builder builder) {  
     servingSize       = builder.servingSize;  
     servings          = builder.servings;  
     calories          = builder.calories;  
     fat               = builder.fat;  
     soduim            = builder.sodium;  
     carbohydrate      = builder.carbohydrate;  

And then use it like this:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).

The example above was taken from Effective Java 2

And that doesn't only applies to constructor. Citing Kent Beck in Implementation Patterns:

setOuterBounds(x, y, width, height);
setInnerBounds(x + 2, y + 2, width - 4, height - 4);

Making the rectangle explicit as an object explains the code better:


I'm using Eclipse to help me clean up some code to use Java generics properly. Most of the time it's doing an excellent job of inferring types, but there are some cases where the inferred type has to be as generic as possible: Object. But Eclipse seems to be giving me an option to choose between a type of Object and a type of '?'.

So what's the difference between:

HashMap<String, ?> hash1;


HashMap<String, Object> hash2;

An instance of HashMap<String, String> matches Map<String, ?> but not Map<String, Object>. Say you want to write a method that accepts maps from Strings to anything: If you would write

public void foobar(Map<String, Object> ms) {

you can't supply a HashMap<String, String>. If you write

public void foobar(Map<String, ?> ms) {

it works!

A thing sometimes misunderstood in Java's generics is that List<String> is not a subtype of List<Object>. (But String[] is in fact a subtype of Object[], that's one of the reasons why generics and arrays don't mix well. (arrays in Java are covariant, generics are not, they are invariant)).

Sample: If you'd like to write a method that accepts Lists of InputStreams and subtypes of InputStream, you'd write

public void foobar(List<? extends InputStream> ms) {

By the way: Joshua Bloch's Effective Java is an excellent resource when you'd like to understand the not so simple things in Java. (Your question above is also covered very well in the book.)

I want to create a large HashMap but the put() performance is not good enough. Any ideas?

Other data structure suggestions are welcome but I need the lookup feature of a Java Map:


In my case I want to create a map with 26 million entries. Using the standard Java HashMap the put rate becomes unbearably slow after 2-3 million insertions.

Also, does anyone know if using different hash code distributions for the keys could help?

My hashcode method:

byte[] a = new byte[2];
byte[] b = new byte[3];

public int hashCode() {
    int hash = 503;
    hash = hash * 5381 + (a[0] + a[1]);
    hash = hash * 5381 + (b[0] + b[1] + b[2]);
    return hash;

I am using the associative property of addition to ensure that equal objects have the same hashcode. The arrays are bytes with values in the range 0 - 51. Values are only used once in either array. The objects are equal if the a arrays contain the same values (in either order) and the same goes for the b array. So a = {0,1} b = {45,12,33} and a = {1,0} b = {33,45,12} are equal.

EDIT, some notes:

  • A few people have criticized using a hash map or other data structure to store 26 million entries. I cannot see why this would seem strange. It looks like a classic data structures and algorithms problem to me. I have 26 million items and I want to be able to quickly insert them into and look them up from a data structure: give me the data structure and algorithms.

  • Setting the initial capacity of the default Java HashMap to 26 million decreases the performance.

  • Some people have suggested using databases, in some other situations that is definitely the smart option. But I am really asking a data structures and algorithms question, a full database would be overkill and much slower than a good datastructure solution (after all the database is just software but would have communication and possibly disk overhead).

In Effective Java: Programming Language Guide (Java Series)

Chapter 3 you can find good rules to follow when computing hashCode().


If the field is an array, treat it as if each element were a separate field. That is, compute a hash code for each significant element by applying these rules recursively, and combine these values per step 2.b. If every element in an array field is significant, you can use one of the Arrays.hashCode methods added in release 1.5.

Say you're writing method foo() in class A. foo doesn't ever access any of A's state. You know nothing else about what foo does, or how it behaves. It could do anything.

Should foo always be static, regardless of any other considerations? Why not?

It seems my classes are always accumulating many private helper methods, as I break tasks down and apply the only-write-it-once principle. Most of these don't rely on the object's state, but would never be useful outside of the class's own methods. Should they be static by default? Is it wrong to end up with a large number of internal static methods?

Do think hard before creating a static method, but there are times when they are a good solution.

Joshua Bloch in "Item 1: Consider Static Factory Methods Instead of Constructors" in Effective Java makes a very persuasive case that static methods can be very beneficial. He gives the java.util.Collections class's 32 static factory methods as an example.

In one case, I have a hierarchy of POJO classes whose instances can be automatically serialized into XML and JSON, then deserialized back into objects. I have static methods that use Java generics to do deserialization: fromXML(String xml) and fromJSON(String json). The type of POJO they return isn't known a priori, but is determined by the XML or JSON text. (I originally packaged these methods into a helper class, but it was semantically cleaner to move these static methods into the root POJO class.)

A couple of other examples:

  • Using a class as a namespace to group related methods (eg, java.lang.Math).
  • The method truly is a private class-specific helper method with no need to access instance variables (the case cited here). Just don't sneak a this-equivalent into its argument list!

But don't use statics unthinkingly or you run the danger of falling into a more disorganized and more procedural style of programming.

Is it slower to iterate through a list in Java like this:

for (int i=0;i<list.size();i++) {
    .. list.get(i)

as opposed to:

for (Object o: list) {
    ... o

I assume you ask out of pure curiosity and won't cite Knuth (somebody probably will).

I believe that once your code gets compiled, it doesn't make a difference. It does make a difference before (example 2 is a lot more readable and concise), so go for number 2 and do not care about the rest.

Just my 2 cents


Note your code in snippet number 1 calculates list.size() every time the loop runs, that could make it even slower than number 2


Something I had to double check, Joshua Bloch recommends using for each loops (see item 46 of Effective Java). I believe that ends all kinds of discussions. Thanks Josh! :)

There must be a good book/PDF/HTML file that describes the essentials & good practices of annotations in Java. I sort of know what they are from other good Java books, but I'm looking for something that would teach me most of what I would need to know to make good use of them. (preferably in PDF/HTML so I can print it out & read at my leisure, book ok also but those go out of date so fast...)

Any recommendations?

edit: I found the Sun guides, as well as tutorials like these from O'Reilly and DevX, and the section of Effective Java that covers them... OK, so I know what they are and what tools to read them, but that doesn't tell me much about how they are put to use in practice. (other than a little bit in Effective Java and the O'Reilly article above that suggest their use in automated testing frameworks)

This is more of a subjective question, so I'm going to preemptively mark it as community wiki.

Basically, I've found that in most of my code, there are many classes, many of which use each other, but few of which are directly related to each other. I look back at my college days, and think of the traditional class Cat : Animal type examples, where you have huge inheritance trees, but I see none of this in my code. My class diagrams look like giant spiderwebs, not like nice pretty trees.

I feel I've done a good job of separating information logically, and recently I've done a good job of isolating dependencies between classes via DI/IoC techniques, but I'm worried I might be missing something. I do tend to clump behavior in interfaces, but I simply don't subclass.

I can easily understand subclassing in terms of the traditional examples such as class Dog : Animal or class Employee : Person, but I simply don't have anything that obvious I'm dealing with. And things are rarely as clear-cut as class Label : Control. But when it comes to actually modeling real entities in my code as a hierarchy, I have no clue where to begin.

So, I guess my questions boil down to this:

  1. Is it ok to simply not subclass or inherit? Should I be concerned at all?
  2. What are some strategies you have to determine objects that could benefit from inheritance?
  3. Is it acceptable to always inherit based on behavior (interfaces) rather than the actual type?

Generally, favour composition over inheritance. Inheritance tends to break encapsulation. e.g. If a class depends on a method of a super class and the super class changes the implementation of that method in some release, the subclass may break.

At times when you are designing a framework, you will have to design classes to be inherited. If you want to use inheritance, you will have to document and design for it carefully. e.g. Not calling any instance methods (that could be overridden by your subclasses) in the constructor. Also if its a genuine 'is-a' relationship, inheritance is useful but is more robust if used within a package.

See Effective Java (Item 14, and 15). It gives a great argument for why you should favour composition over inheritance. It talks about inheritance and encapsulation in general (with java examples). So its a good resource even if you are not using java.

So to answer your 3 questions:

Is it ok to simply not subclass or inherit? Should I be concerned at all? Ans: Ask yourself the question is it a truly "is-a" relationship? Is decoration possible? Go for decoration

// A collection decorator that is-a collection with 
public class MyCustomCollection implements java.util.Collection {
    private Collection delegate;
    // decorate methods with custom code

What are some strategies you have to determine objects that could benefit from inheritance? Ans: Usually when you are writing a framework, you may want to provide certain interfaces and "base" classes specifically designed for inheritance.

Is it acceptable to always inherit based on behavior (interfaces) rather than the actual type? Ans: Mostly yes, but you'd be better off if the super class is designed for inheritance and/or under your control. Or else go for composition.

I have two ways to define constants. First one holds the bunch of static final DataType variables in a class and another by using Enum.

Here is the fist type:

public class TipTipProperties {
    public static final String MAX_WIDTH_AUTO = "auto";
    public static final String POSITION_RIGHT = "right";    

And the usage of these variable will via static call, as an example: TipTipProperties.MAX_WIDTH_AUTO

And the second type is:

public enum TipTipProperties {


    private MaxWidth maxWidth;
    private Position position;  

    private TipTipProperties(MaxWidth maxWidth) {
        this.maxWidth = maxWidth;

    private TipTipProperties(Position position) {       
        this.position = position;

    public MaxWidth getMaxWidth() {
        return maxWidth;

    public Position getPosition() {
        return position;

    public enum MaxWidth {

        private String width;

        private MaxWidth(String width) {
            this.width = width;

        public String getWidth() {
            return width;

    public enum Position {

        private String position;

        private Position(String position) {
            this.position = position;

        public String getPosition() {
            return position;

As an example usage: TipTipProperties.POSITION_RIGHT.getPosition().getPosition().

My question is:

  • Which one is better OOP and why?
  • Is there any alternatives or better approach exists?

Thanks in advance.

Enum is the best to do this as Joshua Bloch said in Effective Java,you will have more control using Enum like if you want to print all constants,you can. with class constants you can not have type safety.read this for further help

I'd like to model an Address as a value object. As it is a good practice to make it immutable, I chose not to provide any setter, that might allow to modify it later.

A common approach is to pass the data to the constructor; however, when the value object is pretty big, that may become quite bloated:

class Address {
    public function __construct(
        Point $location,
        $country) {
        // ...

Another approach whould be to provide the arguments as an array, resulting in a clean constructor, but that might mess up the implementation of the constructor:

class Address {
    public function __construct(array $parts) {
        if (! isset($parts['location']) || ! $location instanceof Point) {
            throw new Exception('The location is required');
        $this->location = $location;
        // ...
        if (isset($parts['poBox'])) {
            $this->poBox = $parts['poBox'];
        // ...

That also looks a bit unnatural to me.

Any advice on how to correctly implement a pretty big value object?

The main issue with large list of parameters is readability and the danger that you will mix up parameters. You can tackle these issues with Builder pattern as described in Effective Java. It makes code more readable (especially languages that don't support named and optional parameters):

public class AddressBuilder {
    private Point _point;
    private String _houseNumber;

    // other parameters

    public AddressBuilder() {

    public AddressBuilder WithPoint(Point point) {
        _point = point;
        return this;

    public AddressBuilder WithHouseNumber(String houseNumber) {
        _houseNumber = houseNumber;
        return this;

    public Address Build() {
        return new Address(_point, _houseNumber, ...);

Address address = new AddressBuilder()

The advantages:

  • parameters are named so it is more readable
  • harder to mix up house number with region
  • can use your own order of parameters
  • optional parameters can be omitted

One disadvantage I can think of is that forgetting to specify one of the arguments (not calling WithHouseNumber for example) will result in a run time error, instead of compile time error when using constructor. You should also consider using more Value Objects like PostalCode for example (as oppose to passing a string).

On a related note, sometimes business requirements call for changing part of the Value Object. For example, when address was originally entered, the street number might have been misspelled and needs to be corrected now. Since you modeled Address as an immutable object there is not setter. One possible solution to this problem is to introduce a 'Side-Effect-Free function' on the Address Value Object. The function would return a copy of the object itself with the exception of a new street name:

public class Address {
    private readonly String _streetName;
    private readonly String _houseNumber;


    public Address WithNewStreetName(String newStreetName) {
        // enforce street name rules (not null, format etc)

        return new Address(
            // copy other members from this instance


In a world before Java 1.5 (so no enum) and with my object being serialized, how can I enforce proper instance control? I'm talking about a class like this, where, as far as I can tell, I'm not sure that instance0 and instance1 will always be the only instances.

import java.io.Serializable;

public final class Thing implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final Thing instance0 = new Thing();
    public static final Thing instance1 = new Thing();

    private Thing(){};

You should really check out Effective Java. The chapter on Singleton addresses this somewhat, and there is a chapter on the Typesafe Enum pattern that was definitely an influence on the way enum was implemented.

The short answer is you have to implement readResolve.

Can a class that does not have final modifier in it be fully immutable ?

For example, is the following class immutable ?

class Animal
    private String animalName;

    public Animal(String name) {
        animalName = name;

    public String getName() { return animalName; }

No, your Animal class is not immutable, because it allows subclassing.

Why not?

See this example subclass:

public class ExceptionalAnimal extends Animal {

    public ExceptionalAnimal() {

    public String getName() {
        throw new AssertionError("Oops.. where did that come from?");

Why does this matter?

Immutability is commonly used to guarantee:

  1. That the state of an object doesn't change after construction
  2. That objects are thread-safe
  3. That objects behave in a certain way

If a class allows subclassing, none of these guarantees can be relied upon. If you have a method accepting an Animal as a parameter, anyone can pass in a subclass that breaks these guarantees.

Fix: No public or protected constructors

One often used technique is to not have any public or protected constructors. This prevents subclassing from outside your package and inside your package you could still have your own internal subclasses. Which you cannot if the class is final.

The immutable collection classes from Google's Guava library use this technique. From the Javadoc:

Although this class is not final, it cannot be subclassed as it has no public or protected constructors. Thus, instances of this type are guaranteed to be immutable.

A client can create ImmutableLists with the static of() and copyOf methods.

See also Effective Java, Item 4: Enforcing noninstantiability with a private constructor.

Be aware that guaranteeing immutability by having no public or protected constructors is easier to break than making the class final. For example Mockito will let you mock these cases by default:

ImmutableList notSoImmutable = mock(ImmutableList.class)
when(notSoImmutable.size()).thenThrow(new AssertionError("Oops.. where did that come from?"));

On package private classes

As your Animal class is package private it is not possible to create subclasses of it outside of its package. So assuming that in its package you only create subclasses of Animal that respect it's contract, the class is actually immutable.

For my answer I assumed that Animal is public. If you were interested specifically in package private classes, please ignore my answer ;-)

I am wondering about correct definition for such construction:

class A {
 public static A create() {
    return new A();

 private A() {

In Effective Java (Item 1) and on wikipedia article I found that this is called Static Factory Method (some kind of Factory Method).

But during reading of Refactoring to Patterns (Chapter 6) I met the same construction called Creation Method. Also, there is a note that it should not be messed up with a Factory Method pattern.

Where truth is?

Have a read of this discussion of Factory Method.

FactoryMethodPattern is different from FactoryMethod or CreationMethod.

If enums are used from jdk1.5 onwards , what was the use of java.util.Enumeration interface before jdk1.5 ? Can anybody help me explore this with an example please ?

Enumeration is an early Java class essentially replaced by Iterator. it is used for iteration of certain largely outdated collections.

Enums are Java's version of typesafe enums in the C/C++ sense. They represent a finite and fixed set of values that are canonical but can also have behaviour. They stem from the pattern established by Joshua Bloch in Effective Java.

In other words, they're not related.

public class SomeClass {
    private HashSet<SomeObject> contents = new HashSet<SomeObject>();
    private Set<SomeObject> contents2 = new HashSet<SomeObject>();

What's the difference? In the end they are both a HashSet isn't it? The second one looks just wrong to me, but I have seen it frequently used, accepted and working.

Set is an interface that HashSet implements, so if you do this:

Set<E> mySet = new HashSet<E>();

You will still have access to the functionality of HashSet, but you also have the flexibility to replace the concrete instance with an instance of another Set class in the future, such as LinkedHashSet or TreeSet, or another implementation.

The first method uses a concrete class, allowing you to replace the class with an instance of itself or a subclass, but with less flexibility. For example, TreeSet could not be used if your variable type was HashSet.

This is Item 52 from Joshua Bloch's Effective Java, 2nd Edition.

Refer to Objects by their interfaces

... You should favor the use of interfaces rather than classes to refer to objects. If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types. The only time you really need to refer to an object's class is when you're creating it with a constructor...

// Usually Good - uses interface as type

List<T> tlist = new Vector<T>();

// Typically Bad - uses concrete class as type!

Vector<T> vec = new Vector<T>();

This practice does carry some caveats - if the implementation you want has special behavior not guaranteed by the generic interface, then you have to document your requirements accordingly.

For example, Vector<T> is synchronized, whereas ArrayList<T> (also an implementer of List<T>) does not, so if you required synchronized containers in your design (or not), you would need to document that.

I saw this post :


and I'm not familiar with java APIs, which books do you think will really help me get familiar with those APIs?

Effective Java by Josh Bloch

Java in a Nutshell, David Flanagan

Java 7- complete reference This books not out yet but it might help a lot along with the java docs and all the additional material the others have mentioned.

I was doing a little research on the difference between the two, and I noticed that .equals seems to simply be more reliable than ==. Is there a reason to use == over .equals other than the (I'm assuming) speed increase?

I'm doing this research because I'm doing a little work with Java. Would there be a more important distinction in usage when you consider other languages, like C# or C++? If so, could you tell me why?

EDIT: Maybe I should clarify. When I said that .equals is more reliable, I meant that I can't think of a comparison that .equals wouldn't be appropriate for, but it's easy to come up with situations in which you should avoid ==. Can anyone provide me with a rather specific example of when you'd use ==, but not .equals?

As others have said, == compares references while .equals compares values. == is faster than .equals, but if more than one instance of an object can have the same value and you are comparing the values, you can't use == and expect it to be right. If the two objects are a different instance, but have the same value, == will return false.

That said, there are some immutable objects that implement "instance control".

They do this using a static factory method. The class will define a static Map of instances of all the objects of itself that have been created. The static factory method will instantiate an object with the parameters passed to it. But, before returning the object, it checks the Map to see if it has an object of the same value.

If it finds one that is equal, it returns the object in the Map that has the same value instead of the newly created object.

If it does not find an object that is equal, it adds the newly created object to the Map and returns the new object.

The advantage of this is that, for objects that implement instance control, it is safe to use == to check for value equality because there is no way that two objects with the same value will ever exist.

Effective Java discusses instance control in Chapter 2.

Guava has classes called Interners that make it trivial for a class that wants to implement instance control to do so by storing objects of itself in the Interner construct.

Immutable objects that implement instance control like this should indicate that they do in their documentation. If they do, you know it is safe to use == to check for value equality. But, for any immutable objects that do not implement instance control, you should always use .equals to check for value equality.

I was reading Joshua Bloch's "Effective Java Programming Language Guide".
He explains static factory methods could be used to avoid unnecessary duplicate objects.
I haven't quite understood this.
Could anyone explain?

One real-world example:

Java supports both primitive and object types to represent a byte. When you convert a primitive to object you could do something like:

Byte b = new Byte( (byte) 65);

Butt this would create a new instance for every call. Instead you do:

Byte b = Byte.valueOf( (byte) 65);

On every call, the method valueOf() will returns the same instance of a Byte object representing the byte value 65.

After 10000 calls the 1st example would have created 10000 objects, whereas the second only one, because Byte class has an internal cache of Byte objects representing all numbers between -128 and 127.

Does anyone know if there is a type of community based code standards and best practices web site\tool? Maybe similar to Stackoverflow where the community votes on the best practices. I've tried to build a full reference tool for my developers but it just turns into my own version of Clean Code or Effective Java. I've asked all my team members to read these books and similar ones for reference but I was just interested to see if there was a community based tool.

This site is a good place to start http://c2.com/cgi/wiki?JavaIdioms

I am writing a class (Foo) which, when instantiated, can be called from multiple threads.

Most methods of the Foo class can safely be called by multiple threads in parallel. One method of this class (logout()), requires that all other threads are done.

Before logout is called, the reference to foo is deleted from a thread-safe collection. So, no new thread will get a reference to the Foo object. However, there may be existing threads that are working on references to the Foo object that needs to be logged out.

I could have a counter that is incremented every time a thread enters the object, and decremented every time a thread leaves. In logout(), I could spin on while (counter != 0);

But I am thinking there is probably a better defined way/pattern out there to do this. Looking for the wisdom of the stackoverflow community here.

If you're using Java 1.5 or later, be sure to read up on Doug Lea's java.util.concurrent. It has some extremely nice facilities that you may be able to leverage, and as Joshua Bloch says in Effective Java: "Given the difficulty of using wait and notify correctly, you should use the higher-level concurrency utilities instead." (p. 273).

One java.util.concurrent approach to consider is to use a ThreadPoolExecutor, which queues up a set of concurrent tasks (Runnables) and distributes them across a pool of worker threads. Your logout operation might then call ExecutorService.shutdown() to cause it to stop accepting new tasks. Then you can call ExecutorService.isTerminated() to detect when the last task has completed.