Java Reference
In-Depth Information
threads to be spawned simultaneously. This results in too many locks in contention and too
much context switching. If you want to deal with thousands of concurrent connections or
more, it's usually better to go nonblocking.
Key Points
▪ Event-driven architectures are easy to implement using lambda-based callbacks.
▪ A
CompletableFuture
represents an IOU for a value. They can be easily composed and
combined using lambdas.
▪ An
Observable
extends the idea of a
CompletableFuture
to streams of data.
Exercises
There's really only one exercise for this chapter, and it requires refactoring some code to use
a
CompletableFuture
. We'll start out with the
BlockingArtistAnalyzer
class shown in
the names, and returns
true
if the first artist has more members and
false
otherwise. It is
injected with an
artistLookupService
that may take some time to look up the
Artist
in
question. Because
BlockingArtistAnalyzer
blocks on this service twice sequentially, the
analyzer can be slow; the goal of our exercise is to speed it up.
Example 9-18. The BlockingArtistAnalyzer tells its clients which Artist has more members
public
public class
class
BlockingArtistAnalyzer
BlockingArtistAnalyzer
{
private
private final
final
Function
<
String
,
Artist
>
artistLookupService
;
public
public
BlockingArtistAnalyzer
(
Function
<
String
,
Artist
>
artistLookupService
) {
this
this
.
artistLookupService
=
artistLookupService
;
}
public
public
boolean
boolean
isLargerGroup
(
String artistName
,
String otherArtistName
) {
return
return
getNumberOfMembers
(
artistName
) >
getNumberOfMembers
(
otherArtistName
);
}
private
private
long
long
getNumberOfMembers
(
String artistName
) {
return
return
artistLookupService
.
apply
(
artistName
)
.
getMembers
()