3 questions
2 solutions
1 problem
Multithreading
Multithreading
Multithreading
Multithreading
Parallel computing
Parallel computing
Parallel computing
Parallel computing
Parallel computing
Parallel computing
Java & API
Java & API
http://www.flickr.com/photos/jmchuff/
Multicore processors
Multicore processors
Multicore processors
On the sofware side
On the sofware side
A classical example
public class Singleton {
private static Singleton instance ;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton() ;
}
return instance ;
} }
A classical example
A classical example
public class Singleton {
private static Singleton instance ;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton() ;
}
return instance ;
} }
A classical example
A classical example
public class Singleton {
private static Singleton instance ;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton() ;
}
return instance ;
} }
public class Singleton {
private static Singleton instance ;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton() ;
}
return instance ;
} }
A classical example
public class Singleton {
private static Singleton instance ;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton() ;
}
return instance ;
} }
A classical example
A classical example
A classical example
public class Singleton {
private static Singleton instance ;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton() ;
}
return instance ;
} }
A classical example
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 ;
}
}
A classical example
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 ;
}
}
A classical example
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 ;
}
}
A classical example
Solution to the « data race »
Solution to the « data race »
Solution to the « data race »
Solution to the « data race »
Solution to the « data race »
The JLS
The JLS
The JLS
The JLS
The JLS
The JLS
The JLS
The JLS
The JLS
The JLS
Happens before
x = 1
r1 = x
Happens before
x = 1
r1 = x
Happens before
x = 1
r1 = x
Happens before
r1 1
x = 1
r1 = x
Happens before
Happens before
Example : normal read / write
private int index ;
public void gloriousIncrementation() {
index++ ;
}
public void happyTesting() {
if (index > 10) {
System.out.println("Index is BIG!") ;
}
}
private int index ;
public void gloriousIncrementation() {
index++ ;
}
public void happyTesting() {
if (index > 10) {
System.out.println("Index is BIG!") ;
}
}
Example : normal read / write
private volatile int index ;
public void gloriousIncrementation() {
index++ ;
}
public void happyTesting() {
if (index > 10) {
System.out.println("Index is BIG!") ;
}
}
Example : volatile read / write
Problematic case
public void niceMethod() {
x = 1 ;
synchronized(lock) {
y = 1 ;
}
}
public void coolMethod() {
synchronized(lock) {
r1 = y ;
}
r2 = x ;
}
private int x, y, r1, r2 ;
private Object lock = new Object() ;
public void niceMethod() {
x = 1 ;
synchronized(lock) {
y = 1 ;
}
}
public void coolMethod() {
synchronized(lock) {
r1 = y ;
}
r2 = x ;
}
private int x, y, r1, r2 ;
private Object lock = new Object() ;
Problematic case
public void niceMethod() {
x = 1 ;
synchronized(lock) {
y = 1 ;
}
}
public void coolMethod() {
synchronized(lock) {
r1 = y ;
}
r2 = x ;
}
private int x, y, r1, r2 ;
private Object lock = new Object() ;
Problematic case
public void niceMethod() {
x = 1 ;
synchronized(lock) {
y = 1 ;
}
}
public void coolMethod() {
synchronized(lock) {
r1 = y ;
}
r2 = x ;
}
private int x, y, r1, r2 ;
private Object lock = new Object() ;
Problematic case
r1 = 1, r2 = 1
public void niceMethod() {
x = 1 ;
synchronized(lock) {
y = 1 ;
}
}
public void coolMethod() {
synchronized(lock) {
r1 = y ;
}
r2 = x ;
}
private int x, y, r1, r2 ;
private Object lock = new Object() ;
Problematic case
public void niceMethod() {
x = 1 ;
synchronized(lock) {
y = 1 ;
}
}
public void coolMethod() {
synchronized(lock) {
r1 = y ;
}
r2 = x ;
}
private int x, y, r1, r2 ;
private Object lock = new Object() ;
Problematic case
public void niceMethod() {
x = 1 ;
synchronized(lock) {
y = 1 ;
}
}
public void coolMethod() {
synchronized(lock) {
r1 = y ;
}
r2 = x ;
}
private int x, y, r1, r2 ;
private Object lock = new Object() ;
Problematic case
r1 = 0, r2 = ?
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 ;
}
}
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 ;
}
}
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 ;
}
}
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 ;
}
}
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 ;
}
}
Back to the double check locking
Is there an elegant solution ?
Is there an elegant solution ?
public enum Singleton {
instance ;
}
Is there an elegant solution ?
public enum Singleton {
instance ;
}
Example
private Object o = new Object() ;
private int index = 0 ;
public void slickMethod() {
synchronized (o) {
index++ ;
}
}
private Object o = new Object() ;
private int index = 0 ;
public void slickMethod() {
synchronized (o) {
index++ ;
}
}
Example
private Object o = new Object() ;
private int index = 0 ;
public void slickMethod() {
synchronized (o) {
index++ ;
}
}
Example
Memory barrier
Memory barrier
Optimization 1
Optimization 1
Optimization 1
Optimization 1
Optimization 2
Optimization 2
Cache trap !
Cache trap !
False sharing
False sharing
Variable padding
public class Sequence {
private static final AtomicLongFieldUpdater<Sequence> updater =
AtomicLongFieldUpdater.newUpdater(Sequence.class, "value");
private volatile long p1 = 7L, p2 = 7L, p3 = 7L, p4 = 7L,
p5 = 7L, p6 = 7L, p7 = 7L ;
private volatile long value = Sequencer.INITIAL_CURSOR_VALUE ;
private volatile long q1 = 7L, q2 = 7L, q3 = 7L, q4 = 7L,
q5 = 7L, q6 = 7L, q7 = 7L;
// ...
public long sumPaddingToPreventOptimisation() {
return p1 + p2 + p3 + p4 + p5 + p6 + p7 + value +
q1 + q2 + q3 + q4 + q5 + q6 + q7;
}
public void setPaddingValue(final long value) {
p1 = p2 = p3 = p4 = p5 = p6 = p7 = q1 = q2 = q3 = q4 = q5 = q6 = q7 = value;
}
}
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; }
How to write efficient concurrent code ?
How to write efficient concurrent code ?
Runnable r = new Runnable() { public void run() { while (true) { System.out.println(« Let’s go sailing !") ; } } } ; Thread t = new Thread(r) ; t.start() ;
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) ;
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++ ;
}
Lock interface
private Lock lock = new ReentrantLock() ; public void crispyMethod() { lock.lock() ; // blocking call as synchronized // ... lock.unlock() ; } ;
Lock interface
private Lock lock = new ReentrantLock() ; public void crispyMethod() { lock.tryLock(10, TimeUnit.MILLISECONDS) ; // timeout // ... lock.unlock() ; } ;
Semaphore interface
private Semaphore s = new Semaphore(5) ; public void maMethode() { s.acquire() ; // blocking call as synchronized // ... s.release() ; } ;
Semaphore interface
private Semaphore s = new Semaphore(5) ; public void maMethode() { s.tryAcquire(10, TimeUnit.MILLISECONDS) ; // timeout // ... s.release() ; } ;
Semaphore interface
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 } ;
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) ; } ;
ReadWriteLock Interface
ReadWriteLock Interface
private ReadWriteLock rwLock = new ReentrantReadWriteLock() ;
public void aMethodThatReads() { Lock readLock = rwLock.readLock() ; readLock.lock() ; // reading... readLock.unlock() ; } ;
public void aMethodThatWrites() { Lock writeLock = rwLock.writeLock() ; writeLock.lock() ; // writing... writeLock.unlock() ; } ;
Atomic types
private AtomicInteger index = new AtomicInteger(0) ;
public void uneMethode() {
long newValue = index.incrementAndGet() ;
}
Compare and swap = CAS
Compare and swap = CAS
public final long incrementAndGet() {
for (;;) {
long current = get() ;
long next = current + 1 ;
if (compareAndSet(current, next))
return next ;
}
}
Queue & BlockingQueue interfaces
Queue & BlockingQueue interfaces
Queue & BlockingQueue interfaces
Queue & BlockingQueue interfaces
Queue & BlockingQueue interfaces
add(e) offer(e) put(e) offer(e, time, unit)
remove() poll() take() poll(e, time, unit)
element() peek() - -
CopyOnWriteArrayList
CopyOnWriteArrayList
Immutability
Immutability
Immutability
Try trees
Immutable systems
In databases…
begin
update ... set ... where ...
commit
In databases…
begin
update ... set ... where ...
commit
In databases…
In databases…
STM Pattern
<dependency>
<groupId>se.scalablesolutions.akka</groupId>
<artifactId>akka-kernel</artifactId>
<version>1.3.1</version>
</dependency>
<repository>
<id>Akka</id>
<name>Akka Maven2 Repository</name>
<url>http://akka.io/repository/</url>
</repository>
STM Pattern
final Ref<Integer> source = new Ref<Integer>(500) ;
final Atomic<Object> atom = new Atomic<Object>() {
@Override
public Object atomically() {
source.swap(source.get() + 1) ;
return null ;
}
} ;
atom.execute() ;
STM Pattern
final Ref<Integer> source = new Ref<Integer>(500) ;
final Atomic<Object> atom = new Atomic<Object>() {
@Override
public Object atomically() {
source.swap(source.get() + 1) ;
return null ;
}
} ;
atom.execute() ;
STM Pattern
final Ref<Integer> source = new Ref<Integer>(500) ;
final Atomic<Object> atom = new Atomic<Object>() {
@Override
public Object atomically() {
source.swap(source.get() + 1) ;
return null ;
}
} ;
atom.execute() ;
STM Pattern
STM Pattern
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)) ;
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) ;
}
} ;
STM : implementation
STM : implementation
STM : why is it so important ?
STM : why is it so important ?
STM : why is it so important ?
STM : why is it so important ?
STM : why is it so important ?
STM : why is it so important ?
STM : why is it so important ?
Actors
Actors
Akka Actors
Akka Actors
Akka Actors
public class Vador extends UntypedActor {
public void onReceive(Object o) throws Exception {
// o is the message
// return something ;
getContext().reply(something) ;
}
}
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() ;
}
Akka Actors
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) ;
}
}
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 ;
}
}
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() ;
}
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() ;
}
BTW, the result is…
[2^3989][3^1996][5^996][7^664][11^399][13^331][17^248][19^221][23^180][29^141][31^133][37^110][41^99][43^95][47^86][53^76][59^68][61^66][67^59]
[71^56][73^54][79^50][83^48][89^44][97^41][101^39][103^38][107^37][109^36][113^35][127^31][131^30][137^29][139^28][149^26][151^26][157^25][163^
24][167^23][173^23][179^22][181^22][191^20][193^20][197^20][199^20][211^18][223^17][227^17][229^17][233^17][239^16][241^16][251^15][257^15][263
^15][269^14][271^14][277^14][281^14][283^14][293^13][307^13][311^12][313^12][317^12][331^12][337^11][347^11][349^11][353^11][359^11][367^10][37
3^10][379^10][383^10][389^10][397^10][401^9][409^9][419^9][421^9][431^9][433^9][439^9][443^9][449^8][457^8][461^8][463^8][467^8][479^8][487^8][
491^8][499^8][503^7][509^7][521^7][523^7][541^7][547^7][557^7][563^7][569^7][571^7][577^6][587^6][593^6][599^6][601^6][607^6][613^6][617^6][619
^6][631^6][641^6][643^6][647^6][653^6][659^6][661^6][673^5][677^5][683^5][691^5][701^5][709^5][719^5][727^5][733^5][739^5][743^5][751^5][757^5]
[761^5][769^5][773^5][787^5][797^5][809^4][811^4][821^4][823^4][827^4][829^4][839^4][853^4][857^4][859^4][863^4][877^4][881^4][883^4][887^4][90
7^4][911^4][919^4][929^4][937^4][941^4][947^4][953^4][967^4][971^4][977^4][983^4][991^4][997^4][1009^3][1013^3][1019^3][1021^3][1031^3][1033^3]
[1039^3][1049^3][1051^3][1061^3][1063^3][1069^3][1087^3][1091^3][1093^3][1097^3][1103^3][1109^3][1117^3][1123^3][1129^3][1151^3][1153^3][1163^3
][1171^3][1181^3][1187^3][1193^3][1201^3][1213^3][1217^3][1223^3][1229^3][1231^3][1237^3][1249^3][1259^3][1277^3][1279^3][1283^3][1289^3][1291^
3][1297^3][1301^3][1303^3][1307^3][1319^3][1321^3][1327^3][1361^2][1367^2][1373^2][1381^2][1399^2][1409^2][1423^2][1427^2][1429^2][1433^2][1439
^2][1447^2][1451^2][1453^2][1459^2][1471^2][1481^2][1483^2][1487^2][1489^2][1493^2][1499^2][1511^2][1523^2][1531^2][1543^2][1549^2][1553^2][155
9^2][1567^2][1571^2][1579^2][1583^2][1597^2][1601^2][1607^2][1609^2][1613^2][1619^2][1621^2][1627^2][1637^2][1657^2][1663^2][1667^2][1669^2][16
93^2][1697^2][1699^2][1709^2][1721^2][1723^2][1733^2][1741^2][1747^2][1753^2][1759^2][1777^2][1783^2][1787^2][1789^2][1801^2][1811^2][1823^2][1
831^2][1847^2][1861^2][1867^2][1871^2][1873^2][1877^2][1879^2][1889^2][1901^2][1907^2][1913^2][1931^2][1933^2][1949^2][1951^2][1973^2][1979^2][
1987^2][1993^2][1997^2][1999^2][2003^1][2011^1][2017^1][2027^1][2029^1][2039^1][2053^1][2063^1][2069^1][2081^1][2083^1][2087^1][2089^1][2099^1]
[2111^1][2113^1][2129^1][2131^1][2137^1][2141^1][2143^1][2153^1][2161^1][2179^1][2203^1][2207^1][2213^1][2221^1][2237^1][2239^1][2243^1][2251^1
][2267^1][2269^1][2273^1][2281^1][2287^1][2293^1][2297^1][2309^1][2311^1][2333^1][2339^1][2341^1][2347^1][2351^1][2357^1][2371^1][2377^1][2381^
1][2383^1][2389^1][2393^1][2399^1][2411^1][2417^1][2423^1][2437^1][2441^1][2447^1][2459^1][2467^1][2473^1][2477^1][2503^1][2521^1][2531^1][2539
^1][2543^1][2549^1][2551^1][2557^1][2579^1][2591^1][2593^1][2609^1][2617^1][2621^1][2633^1][2647^1][2657^1][2659^1][2663^1][2671^1][2677^1][268
3^1][2687^1][2689^1][2693^1][2699^1][2707^1][2711^1][2713^1][2719^1][2729^1][2731^1][2741^1][2749^1][2753^1][2767^1][2777^1][2789^1][2791^1][27
97^1][2801^1][2803^1][2819^1][2833^1][2837^1][2843^1][2851^1][2857^1][2861^1][2879^1][2887^1][2897^1][2903^1][2909^1][2917^1][2927^1][2939^1][2
953^1][2957^1][2963^1][2969^1][2971^1][2999^1][3001^1][3011^1][3019^1][3023^1][3037^1][3041^1][3049^1][3061^1][3067^1][3079^1][3083^1][3089^1][
3109^1][3119^1][3121^1][3137^1][3163^1][3167^1][3169^1][3181^1][3187^1][3191^1][3203^1][3209^1][3217^1][3221^1][3229^1][3251^1][3253^1][3257^1]
[3259^1][3271^1][3299^1][3301^1][3307^1][3313^1][3319^1][3323^1][3329^1][3331^1][3343^1][3347^1][3359^1][3361^1][3371^1][3373^1][3389^1][3391^1
][3407^1][3413^1][3433^1][3449^1][3457^1][3461^1][3463^1][3467^1][3469^1][3491^1][3499^1][3511^1][3517^1][3527^1][3529^1][3533^1][3539^1][3541^
1][3547^1][3557^1][3559^1][3571^1][3581^1][3583^1][3593^1][3607^1][3613^1][3617^1][3623^1][3631^1][3637^1][3643^1][3659^1][3671^1][3673^1][3677
^1][3691^1][3697^1][3701^1][3709^1][3719^1][3727^1][3733^1][3739^1][3761^1][3767^1][3769^1][3779^1][3793^1][3797^1][3803^1][3821^1][3823^1][383
3^1][3847^1][3851^1][3853^1][3863^1][3877^1][3881^1][3889^1][3907^1][3911^1][3917^1][3919^1][3923^1][3929^1][3931^1][3943^1][3947^1][3967^1][39
89^1]
Akka Actors
Akka Actors + STM
Akka Actors + STM
public class Balance {
public final int amount ;
public Balance(int amount) {
this.amount = amount ;
}
}
public class Deposit {
public final int amount ;
public Deposit(int amount) {
this.amount = amount ;
}
}
public class Withdrawal {
public final int amount ;
public Balance(int amount) {
this.amount = amount ;
}
}
public class GetBalance {
}
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()))) ;
}
}
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()))) ;
}
}
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()))) ;
}
}
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()))) ;
}
}
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 ;
}
}
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() ;
}
}
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() ;
}
}
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() ;
}
}
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() ;
}
}
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() ;
}
}
Akka actors + STM
Akka actors + STM
Parallel computing in Java
Parallel computing in Java
Parallel computing in Java
Fork / Join
Fork / Join
Fork / Join : patterns
ForkJoinPool pool = new ForkJoinPool() ;
PrimeFactorsFinderRecursiveTask task = new PrimeFactorsFinderRecursiveTask(1, 4000) ; ForkJoinTask<PrimeFactors> pfsTask = pool.submit(task) ; PrimeFactors pfs = pfsTask.get() ;
public class PrimeFactorsFinderRecursiveTask extends RecursiveTask<PrimeFactors> {
private int start, end ;
protected PrimeFactors compute() {
PrimeFactors pfs = new PrimeFactors() ;
if (end - start > ITERATIONS) { // I’m too big
// processing
ForkJoinTask<PrimeFactors> task = ... ;
task.fork() ;
PrimeFactors pfs = task.get() ;
...
} else {
for (int i = start ; i < end ; i++) {
PrimeFactors pfi = pfs.getPrimeFactors(i) ;
pfs.add(pfi) ;
}
}
return pfs ;
}
}
public class PrimeFactorsFinderRecursiveTask extends RecursiveTask<PrimeFactors> {
private int start, end ;
protected PrimeFactors compute() {
PrimeFactors pfs = new PrimeFactors() ;
if (end - start > ITERATIONS) { // I’m too big
// processing
ForkJoinTask<PrimeFactors> task = ... ;
task.fork() ;
PrimeFactors pfs = task.get() ;
...
} else {
for (int i = start ; i < end ; i++) {
PrimeFactors pfi = pfs.getPrimeFactors(i) ;
pfs.add(pfi) ;
}
}
return pfs ;
}
}
public class PrimeFactorsFinderRecursiveTask extends RecursiveTask<PrimeFactors> {
private int start, end ;
protected PrimeFactors compute() {
PrimeFactors pfs = new PrimeFactors() ;
if (end - start > ITERATIONS) { // I’m too big
// processing
ForkJoinTask<PrimeFactors> task = ... ;
task.fork() ;
PrimeFactors pfs = task.get() ;
...
} else {
for (int i = start ; i < end ; i++) {
PrimeFactors pfi = pfs.getPrimeFactors(i) ;
pfs.add(pfi) ;
}
}
return pfs ;
}
}
Fork / Join : patterns
Fork / Join : patterns
// 1st strategy
if (end - start > MAX_ITERATIONS) { // I’m too big
int m = (start + end) / 2 ;
PrimeFactorsFinderTask task1 = new PrimeFactorsFinderTask(start, m) ;
PrimeFactorsFinderTask task2 = new PrimeFactorsFinderTask(m, end) ;
task1.fork() ;
task2.fork() ;
PrimeFactors pfs1 = task1.join() ;
PrimeFactors pfs2 = task2.join() ;
pfs.add(pfs1) ;
pfs.add(pfs2) ;
}
// 2nd strategy
if (end - start > MAX_ITERATIONS) { // I’m too big
List<ForkJoinTask<PrimeFactors>> pfsList = new ArrayList<ForkJoinTask<PrimeFactors>>() ; for (int i = start ; i < end – MAX_ITERATIONS ; i += MAX_ITERATIONS) { PrimeFactorsFinderRecursiveTask task = new PrimeFactorsFinderRecursiveTask(i, i + MAX_ITERATIONS) ; task.fork() ; pfsList.add(task) ; } for (ForkJoinTask<PrimeFactors> task : pfsList) { PrimeFactors pfsElement = task.join() ; pfs.add(pfsElement) ; } }
Parallel Arrays
Parallel Arrays : patterns
ForkJoinPool pool = new ForkJoinPool() ; // package !
ParralelLongArray a = ParralelLongArray.create(size, pool) ;
Parallel Arrays : patterns
a.replaceWithGeneratedValue(new LongGenerator() {
@Override
public long op() {
return rand.nextInt(100) ;
}
}) ;
Parallel Arrays : patterns
Ops.LongPredicate filter = new Ops.LongPredicate() {
@Override
public boolean op(long l1) {
return l1 > 50 ;
}
}
a2 = a.withFilter(filter) ;
a2.all() ;
Parallel Arrays : patterns
Ops.LongReducer reducer = new Ops.LongReducer() {
@Override
public long op(long l1, long l2) {
return l1 + l2 ;
}
}
long reducedValue = a.reduce(reducer, 0L) ;
Parallel Arrays : patterns
Ops.LongOp add2 = new Ops.LongOp() {
@Override
public long op(long l1) {
return l1 + 2 ;
}
} ;
a2 = a.withMapping(add2) ;
Parallel Arrays : patterns
Ops.BinaryLongOp multAB = new Ops.BinaryLongOp() {
@Override
public long op(long l1, long l2) {
return l1*l2 ;
}
} ;
a2 = a0.withMapping(multAB, a1) ;
Parallel Arrays : patterns
Ops.LongReducer sum = new Ops.LongReducer() {
@Override
public long op(long l1, long l2) {
return l1 + l2 ;
}
} ;
long normSquare = a0.withMapping(multAB, a0).reduce(sum, 0L) ;
double norm = Math.sqrt(normSquare) ;
Parallel Arrays : patterns
Java 8 Sept. 2013
What are the l ?
Collection<Person> persons = ... ;
int maxAge = persons.map(p -> p.getAge()).reduce(0, Integer::max) ;
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()) ;
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()) ;
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()) ;
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) ;
}
Supports parallel() !
Collection<Person> persons = ... ;
int maxAge = persons.parallel().map(p -> p.getAge()).reduce(0, Integer::max) ;
Collection<Person> oldies =
persons.parallel().filter(p -> p.age > 40).into(new ArrayList()) ;
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() ;
}
Going parallel with the JDK 8
An anecdot
An anecdot
An anecdot
An anecdot
An anecdot
An anecdot
An anecdot
Algorithms
Algorithms
Algorithms
Conclusions
Conclusions
Conclusions
Conclusions
Conclusions
Conclusions
Thank you !
Q&A