Java Concurrency in Practice

Author: Brian Goetz, Tim Peierls
4.7
All Comments
TopTalkedBooks posted at August 19, 2017
I found Java Concurrency in Practice to be a pretty solid read.

http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/...

TopTalkedBooks posted at August 19, 2017
I have probebly not done much Java Concurrency. Sure you can simulate CSP with Blocking Queues but since you bind real threads you will run into tons of problems.

Why dont we ask Brian Goetz a Java Language Architect how "easy" it is, read his book [1] and then lets talk again how easy it is.

[1] http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/...

TopTalkedBooks posted at August 19, 2017
I think this list is missing some important parts of computer science.

Here are the books that our university uses for first-year students combined with books that I found to be useful:

Introduction to Programming (using Eiffel) [1]

Mathematics for Computer Science (or: Discrete Mathematics) [2]

Introduction to Datastructures and Algorithms [3]

Introduction to Digital Design [4]

Parallel Programming (using Java) [5]

Optional but highly recommended, you'll probably find it completely out of scope:

Real Analysis I [6]

Real Analysis II [7]

Introduction to Linear Algebra [8]

Introduction to Physics [9]

[1]: http://www.amazon.com/Touch-Class-Learning-Program-Contracts...

[2]: http://ocw.mit.edu/courses/electrical-engineering-and-comput...

[3]: http://www.amazon.de/Introduction-Algorithms-Thomas-H-Cormen...

[4]: http://www.amazon.com/Digital-Design-Computer-Architecture-E...

[5]: http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/...

[6]: http://www.amazon.com/Analysis-Texts-Readings-Mathematics-No...

[7]: http://www.amazon.com/Analysis-II-Texts-Readings-Mathematics...

[8]: http://www.amazon.com/Introduction-Linear-Algebra-Fourth-Gil...

[9]: http://www.amazon.com/Fundamentals-Physics-Extended-David-Ha...

TopTalkedBooks posted at August 20, 2017

There is a limited set of events that ensure a write in one thread is visible in another. Thread creation is one of them, so any data written into obj initially should be available in the second thread.

One option would be to synchronize on obj. If the main thread only modified it by calling its synchronized methods and the second thread got the data from an obj synchronized method the main thread writes would be visible in the second thread.

If you really want to learn about multi-threading in Java, I recommend Java Concurrency in Practice

TopTalkedBooks posted at August 20, 2017

Check out this book: Java Concurrency in Practice

TopTalkedBooks posted at August 20, 2017

I would look deeply into Java 5 and the java.util.concurrent package. I'd also recommend reading Brian Goetz' "Java Concurrency in Practice".

TopTalkedBooks posted at August 20, 2017

You question is multi-faceted and I am not going to pretend that I understand all of it. This answer will address only one part of the question.

It doesn't have any kind of backoff: if the UI thread is flooded with jobs this code is going to exacerbate the problem. Some kind of requeueing scheme, whereby the downtime takes into account the latency of the job and some kind of hard-coded sleep is preferable since it means that if the UI job is flooded we're not asking it to do work unduly.

The in-built java.util.concurrent classes such as Task, Service and ScheduledService include facilities to send message updates from a non-UI thread to a UI thread in way that does not flood the UI thread. You could use those classes directly (which would seem advisable, though perhaps that perception is naive of me as I don't fully understand your requirements). Or you can implement a similar custom facility in your code if you aren't using java.util.concurrent directly.

Here is the relevant code from the Task implementation:

/**
 * Used to send message updates in a thread-safe manner from the subclass
 * to the FX application thread. AtomicReference is used so as to coalesce
 * updates such that we don't flood the event queue.
 */
private AtomicReference<String> messageUpdate = new AtomicReference<>();

private final StringProperty message = new SimpleStringProperty(this, "message", "");

/**
 * Updates the <code>message</code> property. Calls to updateMessage
 * are coalesced and run later on the FX application thread, so calls
 * to updateMessage, even from the FX Application thread, may not
 * necessarily result in immediate updates to this property, and
 * intermediate message values may be coalesced to save on event
 * notifications.
 * <p>
 *     <em>This method is safe to be called from any thread.</em>
 * </p>
 *
 * @param message the new message
 */
protected void updateMessage(String message) {
    if (isFxApplicationThread()) {
        this.message.set(message);
    } else {
        // As with the workDone, it might be that the background thread
        // will update this message quite frequently, and we need
        // to throttle the updates so as not to completely clobber
        // the event dispatching system.
        if (messageUpdate.getAndSet(message) == null) {
            runLater(new Runnable() {
                @Override public void run() {
                    final String message = messageUpdate.getAndSet(null);
                    Task.this.message.set(message);
                }
            });
        }
    }
}

The code works by ensuring that a runLater call is only made if the UI has processed (i.e. rendered) the last update.

Internally the JavaFX 8 system runs on a pulse system. Unless there is an unusually long time consuming operation on the UI thread or general system slowdown, each pulse will usually occur 60 times a second, or approximately every 16-17 milliseconds.

You mention the following:

what I need is a job on the UI thread to call elapsedTimeTextField.setText("00:00:00.001") to happen 1ms before a corresponding call elapsedTimeTextField.setText("00:00:00.002").

However, you can see from the JavaFX architecture description that updating the text more than 60 times a second is pointless as the additional updates will never be rendered. The sample code above from Task, takes care of this by ensuring that a UI update request is only ever issued at a time that the UI update thread can actually reflect the new value in the UI.

Some General Advice

This is just advice, it does not directly solve your problem, take it for what you will, some of it might not even be particularly relevant to your situation or problem.

  1. Make clear the problem you are trying to solve in your questions. That is sometimes more important than a description of the symptoms you are experiencing and trying to resolve. It also helps prevent XY questions.
  2. Be clear from the start on what you are actually doing to solve the problem. An mcve can sometimes help here.
  3. For example, your initial problem statement does not state that you may have 10,000 controllers or provide code for what you term to be a controller. There is not much information on the expected length of time for tasks, what the UI display representing task progress and result is, why millisecond accuracy level might be important to display, if task results need to coalesced, if the tasks can be split and run concurrently, how many threads you are using, etc.
  4. Don't try to develop your own higher level concurrency tools from primitives like ConcurrentLinkedQueue.
  5. For your backend segmented work jobs, use high level concurrency utilities from Java SE, such as Executors, ForkJoin and BlockingQueue.
  6. Orchestrate and synchronize the output of backend jobs with your UI using JavaFX concurrency utilities such as Task.
  7. Know that the high level concurrency utilities and JavaFX concurrency tools can be used in unison, like in this example. I.e., the choice of concurrency tools doesn't need to be an either/or situation.
  8. Extensive use of immutable objects can be a lifesaver in concurrent development.
  9. If you will be doing a lot of concurrent development, take time for detailed study of high quality resources on concurrent programming such as Concurrency in Practice.
  10. Concurrency in general is often simply hard to get right.
TopTalkedBooks posted at August 20, 2017

Generally you want to divide the data as coarsely as possible and minimize communication between threads. Communication includes shared data structures, even the lock free ones. Especially the ones where there are shared variables with write access.

Above general "coarse" policy avoids the common pitfalls (for example false sharing) which prevent scaling.

As for your specific problem, I have to confess, I'm not intimate with flood fill algorithms so I'm not immediately able to sketch out a coarse approach.

However if a coarse approach is not feasible and a strategy for locking individual cells is needed, lock striping could be an approach worth investigating in this case.

A lock free implementation is another possibility. Maybe use compare-and-swap type operation to do the writes (InterlockedCompareExchange64 on VS) combined with retry logic if another thread wrote in the same 8x8 pixel 64bit block.

It could be possible to relax the read locking completely. If 2 threads end up painting the same pixels, it may only waste some cycles, but not corrupt the results.

A lock free implementation could be several times faster.

If you are working in Java Java Concurrency in Practice by Goetz is a great book on things like lock striping.

TopTalkedBooks posted at August 20, 2017

First of all, take a look at this SO on reasons not to use Vector. That being said:

1) Vector locks on every operation. That means it only allows one thread at a time to call any of its operations (get,set,add,etc.). There is nothing preventing multiple threads from modifying Bs or their members because they can obtain a reference to them at different times. The only guarantee with Vector (or classes that have similar synchronization policies) is that no two threads can concurrently modify the vector and thus get into a race condition (which could throw ConcurrentModificationException and/or lead to undefined behavior);

2) As above, there is nothing preventing multiple threads to access Cs at the same time because they can obtain a reference to them at different times.

If you need to protect the state of an object, you need to do it as close to the state as possible. Java has no concept of a thread owning an object. So in your case, if you want to prevent many threads from calling setSameString concurrently, you need to declare the method synchronized.

I recommend the excellent book by Brian Goetz on concurrency for more on the topic.

TopTalkedBooks posted at August 20, 2017

Assuming that your problem is a slow external API, a solution could be the use of either threaded programming or asynchronous programming. By default when doing IO, your code will block. This basically means that if you have a method that does an HTTP request to retrieve some JSON your method will tell your operating system that you're going to sleep and you don't want to be woken up until the operating system has a response to that request. Since that can take several seconds, your application will just idly have to wait.

This behavior is not specific to just HTTP requests. Reading from a file or a device such as a webcam has the same implications. Software does this to prevent hogging up the CPU when it obviously has no use of it.

So the question in your case is: Do we really have to wait for one method to finish before we can call another? In the event that the behavior of method_two is dependent on the outcome of method_one, then yes. But in your case, it seems that they are individual units of work without co-dependence. So there is a potential for concurrency execution.

You can start new threads by initializing an instance of the Thread class with a block that contains the code you'd like to run. Think of a thread as a program inside your program. Your Ruby interpreter will automatically alternate between the thread and your main program. You can start as many threads as you'd like, but the more threads you create, the longer turns your main program will have to wait before returning to execution. However, we are probably talking microseconds or less. Let's look at an example of threaded execution.

def main_method
  Thread.new { method_one }
  Thread.new { method_two }
  Thread.new { method_three }
end

def method_one
  # something_slow_that_does_an_http_request
end

def method_two
  # something_slow_that_does_an_http_request
end

def method_three
  # something_slow_that_does_an_http_request
end

Calling main_method will cause all three methods to be executed in what appears to be parallel. In reality they are still being sequentually processed, but instead of going to sleep when method_one blocks, Ruby will just return to the main thread and switch back to method_one thread, when the OS has the input ready.

Assuming each method takes two 2 ms to execute minus the wait for the response, that means all three methods are running after just 6 ms - practically instantly.

If we assume that a response takes 500 ms to complete, that means you can cut down your total execution time from 2 + 500 + 2 + 500 + 2 + 500 to just 2 + 2 + 2 + 500 - in other words from 1506 ms to just 506 ms.

It will feel like the methods are running simultanously, but in fact they are just sleeping simultanously.

In your case however you have a challenge because you have an operation that is dependent on the completion of a set of previous operations. In other words, if you have task A, B, C, D, E and F, then A, B, C, D and E can be performed simultanously, but F cannot be performed until A, B, C, D and E are all complete.

There are different ways to solve this. Let's look at a simple solution which is creating a sleepy loop in the main thread that periodically examines a list of return values to make sure some condition is fullfilled.

def task_1
# Something slow
return results
end

def task_2
# Something slow
return results
end

def task_3
# Something slow
return results
end

my_responses = {}
Thread.new { my_responses[:result_1] = task_1 }
Thread.new { my_responses[:result_2] = task_2 }
Thread.new { my_responses[:result_3] = task_3 }

while (my_responses.count < 3) # Prevents the main thread from continuing until the three spawned threads are done and have dumped their results in the hash.
  sleep(0.1) # This will cause the main thread to sleep for 100 ms between each check. Without it, you will end up checking the response count thousands of times pr. second which is most likely unnecessary.
end

# Any code at this line will not execute until all three results are collected.

Keep in mind that multithreaded programming is a tricky subject with numerous pitfalls. With MRI it's not so bad, because while MRI will happily switch between blocked threads, MRI doesn't support executing two threads simultanously and that solves quite a few concurrency concerns.

If you want to get into multithreaded programming, I recommend this book: http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601

It's centered around Java, but the pitfalls and concepts explained are universal.

TopTalkedBooks posted at August 20, 2017

If you dislike Times New Roman, just change the browser default font to Tahoma or something like.

alt text

Then start here and click your way through Next link. Then there are the API docs, each with examples in the introductory text. E.g. ExecutorService. Then there are books, like Concurrency in Practice.

TopTalkedBooks posted at August 20, 2017

I know this is a cross post from here... but, I think one of the best Java books is Java Concurrency in Practice by Brian Goetz. A rather advanced book - but, it will wear well on your concurrent code and Java development in general.

TopTalkedBooks posted at October 02, 2017
Wow, that's actually kinda tough to answer. There's been a LOT of changes in the Java world in the last 10 years - as you might guess. And I mean both in terms of the language itself, and the tooling and ecosystem as far as libraries and frameworks, etc.

The answer also depends a bit on what exactly you want to do. If you're mainly interested in web apps, it's one thing, "big data" is another world altogether, mobile (Android) has its own ecosystem, etc.

All of that said, here are some thoughts:

Generics and the newer Collections related stuff is one area that changed a lot. There's online documentation at:

https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz...

To get started with the Java 8 stuff, a book like "Java 8 in Action" would be good.

https://www.amazon.com/Java-Action-Lambdas-functional-style-...

Another good intro the Java 8 era stuff is

https://www.amazon.com/Beginning-Java-Language-Features-Expr...

And to make it even harder, Java 9 just dropped, so there's even more new stuff. I just picked up this book myself, but haven't had a lot of time to dig into it yet.

https://www.amazon.com/Java-Programmers-4th-Deitel-Developer...

For frameworks, Spring and Hibernate are both still popular and it wouldn't hurt to brush up on both of those. Spring Boot in particular has caught on for a lot of Java developers.

https://www.amazon.com/Spring-Boot-Action-Craig-Walls/dp/161...

Also, Tomcat is still very popular for hosting java Web applications and services of various sorts. JBoss / Wildfly is still around, but JEE (as J2EE is now known) is not as popular as in the past (even though it has actually improved a LOT).

Play and Dropwizard are two more frameworks you might want to familiarize yourself with

https://www.playframework.com/

http://www.dropwizard.io/1.1.4/docs/

In terms of tools, Eclipse is still popular, IntelliJ is probably the most popular Java IDE these days, and Netbeans seems to have faded from view a bit. Ant has fallen out of favour for builds, with most devs now using either Maven or Gradle. Read up on / play around with both of those and you'll be in good shape there.

Also, Java shops have also been affected by the overall move to "The Cloud" and you can't really ignore that either. If you haven't already, you'll probably want to familiarize yourself with AWS and the AWS SDK.

If you want to work/play in the "big data" space, you'll need some combination of Hadoop, Kafka, Spark, Hive, Storm, Flume, HBase, Impala, etc., etc., etc.

TopTalkedBooks posted at December 01, 2017
In the talk "Clojure Concurrency" [1], Rich Hickey demands that everyone in the room read "Java Concurrency in Practice" [2]. "It will scare the crap out of you."

[1] https://youtu.be/dGVqrGmwOAw?t=23m57s [2] https://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz...

TopTalkedBooks posted at March 18, 2018

An explanation is given with an example in Java Concurrency In Practice chapter 4 section 4.3.5.

public class SafePoint {
    private int x, y;

    private SafePoint(int[] a) {
        this(a[0], a[1]);
    }

    public SafePoint(SafePoint p) {
        this(p.get());
    }

    public SafePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public synchronized int[] get() {
        return new int[] { x, y };
    }

    public synchronized void set(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

The private constructor exists to avoid the race condition that would occur if the copy constructor were implemented as this(p.x, p.y).

What does it mean is, if you did not have a private constructor and you implement copy constructor in following way:

public SafePoint(SafePoint p) {
    this(p.x, p.y);
}

Now assume that thread A is having the access to SafePoint p is executing above copy constructor's this(p.x, p.y) instruction and at the unlucky timing another thread B also having access to SafePoint p executes setter set(int x, int y) on object p. Since your copy constructor is accessing p's x and y instance variable directly without proper locking it could see inconsistent state of object p.

Where as the private constructor is accessing p's variables x and y through getter which is synchronized so you are guaranteed to see consistent state of object p.

TopTalkedBooks posted at March 18, 2018

Although there are some good answers already posted, but here is what I found while reading Java Concurrency in Practice Chapter 3 - Sharing Objects.

Quote from the book.

The publication requirements for an object depend on its mutability:

  • Mutable objects can be published through any mechanism;
  • Effectively immutable objects (whose state will not be modified after publication) must be safely published;
  • Mutable objects must be safely published, and must be either threadsafe or guarded by a lock.

Book states ways to safely publish mutable objects:

To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

  • Initializing an object reference from a static initializer;
  • Storing a reference to it into a volatile field or AtomicReference;
  • Storing a reference to it into a final field of a properly constructed object; or
  • Storing a reference to it into a field that is properly guarded by a lock.

The last point refers to using various mechanisms like using concurrent data structures and/or using synchronize keyword.

Top Books
We collected top books from hacker news, stack overflow, Reddit, which are recommended by amazing people.