What's the best way to handle concurrency issues when using thread-safe collections in Java?


Constantine

This may be naive to me, but I always thought the following code sample would always work and not crash with NullPointerException when using thread safe collections in Java. Unfortunately, thread t2 seems to be able to remove the item from the list between the calls to the containsKey() and get() methods below the two thread declarations. The commented section shows a way to handle this without getting a NullPointerException, since it's just a test to see if the result of get() is null.

My question is, what is the correct way to handle this in Java using thread safe collections? Sure, I could use mutexes or synchronized blocks, but wouldn't this failure destroy many of the benefits and ease of use that thread-safe collections bring? If I have to use mutexes or synchronized blocks, can't I just use non-thread-safe collections? Also, I've always heard (in academia) that checking code for nulls is bad programming practice. Am I just crazy? Is there an easy answer to this question? Thank you in advance.

package test;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Test {
    public static void main(String[] args) {
        final Map<Integer, Integer> test = new ConcurrentHashMap<>();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    test.put(0, 0);
                    Thread.yield();
                }
            }           
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    test.remove(0);
                    Thread.yield();
                }
            }           
        });

        t1.start();
        t2.start();

        while(true) {
            if (test.containsKey(0)) {
                Integer value = test.get(0);
                System.out.println(value);
            }
            Thread.yield();
        }   

        // OR
//      while(true) {
//          Integer value = test.get(0);
//          if (value != null) {
//              System.out.println(value);
//          }
//          Thread.yield();
//      }           
    }
}
Peter Lowry

What is the correct way to handle this in Java using thread safe collections?

Only one operation is performed, so it is atomic. It's also faster.

    Integer value = test.get(0);
    if (value != null) {               
         System.out.println(value);
    }

I've always heard (in academia) that checking code for nulls is bad programming practice. Am I just crazy?

Maybe. I think checking nullif can be a value nullis best practice.

Related


What is the thread safe way to throw an error when using Rcpp

Tommy Jones I am using parallelism RcppThreadin Rcppfunctions . What is the preferred way to throw an error in the middle of a parallel loop? R's API is single-threaded, so I don't think Rcpp::stop()this is thread-safe. RcppThreadThread-safe methods are provid

What is the thread safe way to throw an error when using Rcpp

Tommy Jones I am using parallelism RcppThreadin Rcppfunctions . What is the preferred way to throw an error in the middle of a parallel loop? R's API is single-threaded, so I don't think Rcpp::stop()this is thread-safe. RcppThreadThread-safe methods are provid

What is the thread safe way to throw an error when using Rcpp

Tommy Jones I am using parallelism RcppThreadin Rcppfunctions . What is the preferred way to throw an error in the middle of a parallel loop? R's API is single-threaded, so I don't think Rcpp::stop()this is thread-safe. RcppThreadThread-safe methods are provid

What is the thread safe way to throw an error when using Rcpp

Tommy Jones I am using parallelism RcppThreadin Rcppfunctions . What is the preferred way to throw an error in the middle of a parallel loop? R's API is single-threaded, so I don't think Rcpp::stop()this is thread-safe. RcppThreadThread-safe methods are provid

What is the thread safe way to throw an error when using Rcpp

Tommy Jones I am using parallelism RcppThreadin Rcppfunctions . What is the preferred way to throw an error in the middle of a parallel loop? R's API is single-threaded, so I don't think Rcpp::stop()this is thread-safe. RcppThreadThread-safe methods are provid

What is the thread safe way to throw an error when using Rcpp

Tommy Jones I am using parallelism RcppThreadin Rcppfunctions . What is the preferred way to throw an error in the middle of a parallel loop? R's API is single-threaded, so I don't think Rcpp::stop()this is thread-safe. RcppThreadThread-safe methods are provid

What's the best way to handle dates and timestamps in Java?

Joe Dean: Every time I need to use a date and/or time stamp in Java, I always feel like I'm doing something wrong and spend endless hours trying to find a better way to use the API without having to write my own Date and Time Utility class. Here are some annoy

What's the best way to handle out-of-memory conditions in Java?

Simon Fischer: We have an application that spawns a new JVM and executes code on behalf of the user. Sometimes these memory runs out, in which case they behave very differently. Sometimes they throw OutOfMemoryError and sometimes freeze. I can detect the latte

What's the best way to handle out-of-memory conditions in Java?

Simon Fischer: We have an application that spawns a new JVM and executes code on behalf of the user. Sometimes these memory runs out, in which case they behave very differently. Sometimes they throw OutOfMemoryError and sometimes freeze. I can detect the latte

What's the best way to handle dates and timestamps in Java?

Joe Dean: Every time I need to use a date and/or time scale in Java, I always feel like I'm doing something wrong and spend endless hours trying to find a better way to use the API without having to write my own Date and Time Utility class. Here are some annoy

What's the best way to handle out-of-memory conditions in Java?

Simon Fisher We have an application that spawns a new JVM and executes code on behalf of the user. Sometimes these memory runs out, in which case they behave very differently. Sometimes they throw OutOfMemoryError and sometimes freeze. I can detect the latter

What's the best way to handle out-of-memory conditions in Java?

Simon Fischer: We have an application that spawns a new JVM and executes code on behalf of the user. Sometimes these memory runs out, in which case they behave very differently. Sometimes they throw OutOfMemoryError and sometimes freeze. I can detect the latte

What's the best way to handle dates and timestamps in Java?

Joe Dean: Every time I need to use a date and/or time stamp in Java, I always feel like I'm doing something wrong and spend endless hours trying to find a better way to use the API without having to write my own Date and Time Utility class. Here are some annoy

Best Java thread-safe locking mechanism for collections?

Jason: What is the slowest thread-safety mechanism for controlling multiple accesses to a collection in Java? I'm adding objects to the top of the collection, but I'm not sure what would be the best collection. Is it a bootstrap or a queue? I thought ArrayList

Best Java thread-safe locking mechanism for collections?

Jason: What is the slowest thread-safety mechanism for controlling multiple accesses to a collection in Java? I'm adding objects to the top of the collection, but I'm not sure what would be the best collection. Is it a bootstrap or a queue? I thought ArrayList

Best Java thread-safe locking mechanism for collections?

Jason: What is the slowest thread-safety mechanism for controlling multiple accesses to a collection in Java? I'm adding objects to the top of the collection, but I'm not sure what would be the best collection. Is it a bootstrap or a queue? I thought ArrayList