80. Example : normal read / write
private int index ;
public void gloriousIncrementation() {
index++ ;
}
public void happyTesting() {
if (index > 10) {
System.out.println("Index is BIG!") ;
}
}
81. Example : normal read / write
private int index ;
public void gloriousIncrementation() {
index++ ;
}
public void happyTesting() {
if (index > 10) {
System.out.println("Index is BIG!") ;
}
}
82. Example : volatile read / write
private volatile int index ;
public void gloriousIncrementation() {
index++ ;
}
public void happyTesting() {
if (index > 10) {
System.out.println("Index is BIG!") ;
}
}
83. Problematic case
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() { public void coolMethod() {
x = 1 ; synchronized(lock) {
synchronized(lock) { r1 = y ;
y = 1 ; }
} r2 = x ;
} }
84. Problematic case
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() { public void coolMethod() {
x = 1 ; synchronized(lock) {
synchronized(lock) { r1 = y ;
y = 1 ; }
} r2 = x ;
} }
85. Problematic case
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() { public void coolMethod() {
x = 1 ; synchronized(lock) {
synchronized(lock) { r1 = y ;
y = 1 ; }
} r2 = x ;
} }
86. Problematic case
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() { public void coolMethod() {
x = 1 ; synchronized(lock) {
synchronized(lock) { r1 = y ;
y = 1 ; }
} r2 = x ;
} }
r1 = 1, r2 = 1
87. Problematic case
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() { public void coolMethod() {
x = 1 ; synchronized(lock) {
synchronized(lock) { r1 = y ;
y = 1 ; }
} r2 = x ;
} }
88. Problematic case
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() { public void coolMethod() {
x = 1 ; synchronized(lock) {
synchronized(lock) { r1 = y ;
y = 1 ; }
} r2 = x ;
} }
89. Problematic case
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() { public void coolMethod() {
x = 1 ; synchronized(lock) {
synchronized(lock) { r1 = y ;
y = 1 ; }
} r2 = x ;
} }
r1 = 0, r2 = ?
90. Back to the double check locking
public class Singleton {
private static Singleton instance ;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton() ;
}
}
}
return instance ;
}
}
91. Back to the double check locking
public class Singleton {
private static Singleton instance ;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton() ;
}
}
}
return instance ;
}
}
92. Back to the double check locking
public class Singleton {
private static Singleton instance ;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton() ;
}
}
}
return instance ;
}
}
93. Back to the double check locking
public class Singleton {
private static Singleton instance ;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton() ;
}
}
}
return instance ;
}
}
94. Back to the double check locking
public class Singleton {
private static volatile Singleton instance ;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton() ;
}
}
}
return instance ;
}
}
141. package java.util.concurrent;
/**
*
* @since 1.7
* @author Doug Lea
*/
public class ThreadLocalRandom extends Random {
/**
* The random seed. We can't use super.seed.
*/
private long rnd;
// Padding to help avoid memory contention among seed updates in
// different TLRs in the common case that they are located near
// each other.
private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
}
146. Runnable r = new Runnable() {
public void run() {
while (true) {
System.out.println(« Let’s go sailing !") ;
}
}
} ;
Thread t = new Thread(r) ;
t.start() ;
147. ExecutorService service = new ScheduledThreadPoolExecutor(10) ;
Callable<Boolean> task = new Callable<Boolean>() {
public Boolean call() throws Exception {
int i = 0 ;
while (i++ < 1000) {
System.out.println("Let’s go swimming !") ;
}
return true ;
}
};
Future<Boolean> f = service.submit(task) ;
Boolean b = f.get(100, TimeUnit.MILLISECONDS) ;
148.
149. private Object o = new Object() ;
private int index = 0 ;
public void saltyMethod() {
synchronized (o) {
index++ ;
}
}
private Object o = new Object() ;
private int volatile index = 0 ;
public void pepperedMethod() {
index++ ;
}
150. Lock interface
private Lock lock = new ReentrantLock() ;
public void crispyMethod() {
lock.lock() ; // blocking call as synchronized
// ...
lock.unlock() ;
} ;
155. CountDownLatch Class
private CountDownLatch latch = new CountDownLatch() ;
public void init() {
db.connect() ; // slow operation
latch.countDown() ; // openning of the latch
} ;
public void process() {
latch.await() ; // blocks until the latch is openned
} ;
156. CyclicBarrier Class
private CyclicBarrier barrier = new CyclicBarrier(2) ;
public void processOne() {
// ...
barrier.await() ; // blocks until 4 calls
} ;
public void processTwo() {
// ...
barrier.await(10, TimeUnit.MICROSECONDS) ;
} ;
162. Compare and swap = CAS
public final long incrementAndGet() {
for (;;) {
long current = get() ;
long next = current + 1 ;
if (compareAndSet(current, next))
return next ;
}
}
217. STM Pattern
List<E> queue1 = new ... ;
List<E> queue2 = new ... ;
final Ref<List<E>> refQueue1 =
new Ref<List<E>>(Collections.unmodifiableList(queue1)) ;
final Ref<List<E>> refQueue2 =
new Ref<List<E>>(Collections.unmodifiableList(queue2)) ;
218. final Atomic<Object> atom = new Atomic<Object>() {
@Override
public Object atomically() {
// duplication
List<E> dupQ1 = new ArrayList<>(refQueue1) ;
List<E> dupQ2 = new ArrayList<>(refQueue2) ;
// transfer
E element = duqQ1.remove(...) ;
duqQ2.add(element) ;
// swapping
refQueue1.swap(Collections.unmodifiableList(dupQ1) ;
refQueue2.swap(Collections.unmodifiableList(dupQ2) ;
}
} ;
233. Akka Actors
public class Vador extends UntypedActor {
public void onReceive(Object o) throws Exception {
// o is the message
// return something ;
getContext().reply(something) ;
}
}
234. Akka Actors
public static void main(String[] args) {
Message message = new Message() ;
ActorRef jeff =
Actors.actorOf(Vader.class).start() ;
Future future =
jeff.sendRequestReplyFuture(message) ;
// a bit further away
// beware, it’s not our good ol’ concurrent Future
result = future.get() ;
}
236. public class PrimeFinderActor extends UntypedActor {
public void onReceive(Object o) throws Exception {
List<Integer> bounds = (List<Integer>)o ;
int debut = bounds.get(0) ;
int fin = bounds.get(1) ;
PrimeFactors pfs = new PrimeFactors() ;
for (int i = start ; i < end ; i++) {
PrimeFactors pfi = pfs.getPrimeFactors(i) ;
pfs.add(pfi) ;
}
// return pfs ;
getContext().reply(pfs) ;
}
}
237. public class PrimeFactorCallable implements Callable<PrimeFactors> {
private int debut, fin ;
public PrimeFactorCallable(int debut, int fin) {
this.debut = debut ; this.fin = fin ;
}
public PrimeFactors call() throws Exception {
PrimeFactors pfs = new PrimeFactors() ;
for (int i = debut ; i < fin ; i++) {
PrimeFactors pfi = pfs.getPrimeFactors(i) ;
pfs.add(pfi) ;
}
return pfs ;
}
}
238. public static void main(String[] args) {
Future [] futures = new Future [400] ; // it’s the Akka Future
for (int i = 0 ; i < futures.length ; i++) {
List<Integer> bound = Collections.unmodifiableList(
Arrays.asList(10*i, 10*(i + 1))) ;
ActorRef primeFactorFinder =
Actors.actorOf(PrimeFinderActor.class).start() ;
futures[i] = primeFactorFinder.sendRequestReplyFuture(bound) ;
}
PrimeFactors pfs = new PrimeFactors() ;
for (int i = 0 ; i < futures.length ; i++) {
pfs.add((PrimeFactors)futures[i].get()) ;
}
Actors.registry().shutdownAll() ;
}
239. public static void main(String... args)
throws ExecutionException, InterruptedException {
ExecutorService es = new ScheduledThreadPoolExecutor(10) ;
Future [] futures = new Future [400] ;
for (int i = 0 ; i < futures.length ; i++) {
PrimeFactorCallable callable =
new PrimeFactorCallable(10*i, 10*(i + 1)) ;
futures[i] = es.submit(callable) ;
}
PrimeFactors pfs = new PrimeFactors() ;
for (int i = 0 ; i < futures.length ; i++) {
pfs.add((PrimeFactors)futures[i].get()) ;
}
es.shutdown() ;
}
244. public class Balance { public class Deposit {
public final int amount ; public final int amount ;
public Balance(int amount) { public Deposit(int amount) {
this.amount = amount ; this.amount = amount ;
} }
} }
public class Withdrawal { public class GetBalance {
public final int amount ; }
public Balance(int amount) {
this.amount = amount ;
}
}
245. public class BankAccount extends UntypedTransactor {
private final Ref<Integer> balance = new Ref<Integer>(0) ;
public void atomically(final Object message) {
if (message instanceof Deposit) {
int amount = ((Deposit)message).amount ;
if (amount > 0)
balance.swap(balance.get() + amount) ;
}
if (message instanceof Withdrawal) {
int amount = ((Retrait)message).amount ;
if (amount > 0) {
if (balance.get() < amount) throw new IllegalStateException("...") ;
balance.swap(balance.get() - amount) ;
}
}
if (message instanceof GetBalance)
getContext().replySafe((new Balance(balance.get()))) ;
}
}
246. public class BankAccount extends UntypedTransactor {
private final Ref<Integer> balance = new Ref<Integer>(0) ;
public void atomically(final Object message) {
if (message instanceof Deposit) {
int amount = ((Deposit)message).amount ;
if (amount > 0)
balance.swap(balance.get() + amount) ;
}
if (message instanceof Withdrawal) {
int amount = ((Retrait)message).amount ;
if (amount > 0) {
if (balance.get() < amount) throw new IllegalStateException("...") ;
balance.swap(balance.get() - amount) ;
}
}
if (message instanceof GetBalance)
getContext().replySafe((new Balance(balance.get()))) ;
}
}
247. public class BankAccount extends UntypedTransactor {
private final Ref<Integer> balance = new Ref<Integer>(0) ;
public void atomically(final Object message) {
if (message instanceof Deposit) {
int amount = ((Deposit)message).amount ;
if (amount > 0)
balance.swap(balance.get() + amount) ;
}
if (message instanceof Withdrawal) {
int amount = ((Retrait)message).amount ;
if (amount > 0) {
if (balance.get() < amount) throw new IllegalStateException("...") ;
balance.swap(balance.get() - amount) ;
}
}
if (message instanceof GetBalance)
getContext().replySafe((new Balance(balance.get()))) ;
}
}
248. public class BankAccount extends UntypedTransactor {
private final Ref<Integer> balance = new Ref<Integer>(0) ;
public void atomically(final Object message) {
if (message instanceof Deposit) {
int amount = ((Deposit)message).amount ;
if (amount > 0)
balance.swap(balance.get() + amount) ;
}
if (message instanceof Withdrawal) {
int amount = ((Retrait)message).amount ;
if (amount > 0) {
if (balance.get() < amount) throw new IllegalStateException("...") ;
balance.swap(balance.get() - amount) ;
}
}
if (message instanceof GetBalance)
getContext().replySafe((new Balance(balance.get()))) ;
}
}
249. public class Transfer {
public final ActorRef source ;
public final ActorRef destination ;
public final int amount ;
public Transfert(
final ActorRef source,
final ActorRef destination,
final int amount) {
this.source = source ;
this.destination = destination ;
this.amount = amount ;
}
}
250. public class BankService extends UntypedTransactor {
public Set<SendTo> coordinate(final Object message) {
if (message instanceof Transfer) {
Set<SendTo> s = new HashSet<SendTo>() ;
Transfer t = (Transfer)message ;
if (t.amount > 0) { // validation
s.add(sendTo(t.destination, new Deposit(t.amount))) ;
s.add(sendTo(t.source, new Withdrawal(t.amount))) ;
return Collections.unmodifiableSet(s) ;
}
}
return nobody() ;
}
}
251. public class BankService extends UntypedTransactor {
public Set<SendTo> coordinate(final Object message) {
if (message instanceof Transfer) {
Set<SendTo> s = new HashSet<SendTo>() ;
Transfer t = (Transfer)message ;
if (t.amount > 0) { // validation
s.add(sendTo(t.destination, new Deposit(t.amount))) ;
s.add(sendTo(t.source, new Withdrawal(t.amount))) ;
return Collections.unmodifiableSet(s) ;
}
}
return nobody() ;
}
}
252. public class BankService extends UntypedTransactor {
public Set<SendTo> coordinate(final Object message) {
if (message instanceof Transfer) {
Set<SendTo> s = new HashSet<SendTo>() ;
Transfer t = (Transfer)message ;
if (t.amount > 0) { // validation
s.add(sendTo(t.destination, new Deposit(t.amount))) ;
s.add(sendTo(t.source, new Withdrawal(t.amount))) ;
return Collections.unmodifiableSet(s) ;
}
}
return nobody() ;
}
}
253. public class BankService extends UntypedTransactor {
public Set<SendTo> coordinate(final Object message) {
if (message instanceof Transfer) {
Set<SendTo> s = new HashSet<SendTo>() ;
Transfer t = (Transfer)message ;
if (t.amount > 0) { // validation
s.add(sendTo(t.destination, new Deposit(t.amount))) ;
s.add(sendTo(t.source, new Withdrawal(t.amount))) ;
return Collections.unmodifiableSet(s) ;
}
}
return nobody() ;
}
}
254. public class BankService extends UntypedTransactor {
public Set<SendTo> coordinate(final Object message) {
if (message instanceof Transfer) {
Set<SendTo> s = new HashSet<SendTo>() ;
Transfer t = (Transfer)message ;
if (t.amount > 0) { // validation
s.add(sendTo(t.destination, new Deposit(t.amount))) ;
s.add(sendTo(t.source, new Withdrawal(t.amount))) ;
return Collections.unmodifiableSet(s) ;
}
}
return nobody() ;
}
}
315. What are the l ?
Collection<Person> persons = ... ;
int maxAge = persons.map(p -> p.getAge()).reduce(0, Integer::max) ;
316. What are the l ?
Collection<Person> persons = ... ;
int maxAge = persons.map(p -> p.getAge()).reduce(0, Integer::max) ;
Collection<Person> oldies =
persons.filter(p -> p.age > 40).into(new ArrayList()) ;
317. What are the l ?
Collection<Person> persons = ... ;
int maxAge = persons.map(p -> p.getAge()).reduce(0, Integer::max) ;
Collection<Person> oldies =
persons.filter(p -> p.age > 40).into(new ArrayList()) ;
318. What are the l ?
Collection<Person> persons = ... ;
int maxAge = persons.map(p -> p.getAge()).reduce(0, Integer::max) ;
Collection<Person> oldies =
persons.filter(p -> p.age > 40).into(new ArrayList()) ;
319. The new Collection interface
public interface Collection<E> {
public boolean add(E e) ;
public boolean addAll(Collection<? extends E> c) ;
// the usual methods of the Collection interface
// the new stuff
public void sort(Comparator<? super E> comparator)
default Collections.sort(comparator) ;
}
321. Spliterable Interface
public interface Spliterable<E> extends Iterable<E> {
public Iterable<E>[] splits() ;
public Iterable<E>[] splits(
int maxSplits, int minPerSplits, int maxPerSplits) ;
public int naturalSplits() ;
}