Concurrency Notes2
Concurrency Notes2
1) ExecutorService
2) ExecutorService Example
ExecutorService executorService =
Executors.newFixedThreadPool(10);
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous
task");
}
});
executorService.shutdown();
First an ExecutorService is created using
the newFixedThreadPool() factory method. This
creates a thread pool with 10 threads executing tasks.
Second, an anonymous implementation of
the Runnable interface is passed to
the execute() method. This causes the Runnable to be
executed by one of the threads in
the ExecutorService.
3) ExecutorService Implementations
ThreadPoolExecutor
ScheduledThreadPoolExecutor
4) Creating an ExecutorService
ExecutorService executorService2 =
Executors.newFixedThreadPool(10);
ExecutorService executorService3 =
Executors.newScheduledThreadPool(10);
5) ExecutorService Usage
execute(Runnable)
submit(Runnable)
submit(Callable)
invokeAny(...)
invokeAll(...)
shutdown()
shutdownNow()
I will take a look at each of these methods in the following
sections.
5a) execute(Runnable)
ExecutorService executorService =
Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous
task");
}
});
executorService.shutdown();
System.out.println("future.get() = " +
future.get());
Asynchronous Callable
future.get() = Callable Result
5d) invokeAny()
ExecutorService executorService =
Executors.newSingleThreadExecutor();
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 1";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 2";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 3";
}
});
String result =
executorService.invokeAny(callables);
executorService.shutdown();
This code example will print out the object returned by one
of the Callable's in the given collection. I have tried
running it a few times, and the result changes. Sometimes
it is "Task 1", sometimes "Task 2" etc.
5e) invokeAll()
ExecutorService executorService =
Executors.newSingleThreadExecutor();
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 1";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 2";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 3";
}
});
List<Future<String>> futures =
executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " +
future.get());
}
executorService.shutdown();
6) ExecutorService Shutdown
-------------------------------------------------
AtomicInteger
AtomicIntegerExample.java
01 package com.javacodegeeks.snippets.core;
03 import java.util.concurrent.atomic.AtomicInteger;
04
05 public class AtomicIntegerExample {
06
07 private static AtomicInteger at = new AtomicInteger(0);
08
09 static class MyRunnable implements Runnable {
10
11 private int myCounter;
12 private int myPrevCounter;
13 private int myCounterPlusFive;
14 private boolean isNine;
15
16 public void run() {
17 myCounter = at.incrementAndGet();
System.out.println("Thread " +
18 Thread.currentThread().getId() + " / Counter : " +
myCounter);
19 myPrevCounter = at.getAndIncrement();
System.out.println("Thread " +
20 Thread.currentThread().getId() + " / Previous : " +
myPrevCounter);
21 myCounterPlusFive = at.addAndGet(5);
System.out.println("Thread " +
22 Thread.currentThread().getId() + " / plus five : " +
myCounterPlusFive);
23 isNine = at.compareAndSet(9, 3);
24 if (isNine) {
System.out.println("Thread " +
25
Thread.currentThread().getId()
+ " / Value was equal to 9, so it was updated to
26
" + at.intValue());
27 }
28
29 }
30 }
31
32 public static void main(String[] args) {
33 Thread t1 = new Thread(new MyRunnable());
34 Thread t2 = new Thread(new MyRunnable());
35 t1.start();
36 t2.start();
37 }
38 }
If you run the example, you will see that both threads can
update the AtomicInteger variable atomically.
Output
1 Thread 9 / Counter : 1
2 Thread 10 / Counter : 2
3 Thread 9 / Previous : 2
4 Thread 9 / plus five : 9
5 Thread 9 / Value was equal to 9, so it was updated to 3
6 Thread 10 / Previous : 3
7 Thread 10 / plus five : 8
Q) What is threadLocal?
The ThreadLocal class in Java enables you to create
variables that can only be read and written by the same
thread. Thus, even if two threads are executing the same
code, and the code has a reference to
aThreadLocal variable, then the two threads cannot see
each other's ThreadLocal variables.
Creating a ThreadLocal
Accessing a ThreadLocal
Generic ThreadLocal
myThreadLocal.set("Hello ThreadLocal");
String threadLocalValue =
myThreadLocal.get();
Now all threads will see the same initial value when
calling get() before having called set() .
@Override
public void run() {
threadLocal.set( (int)
(Math.random() * 100D) );
try {
Thread.sleep(2000);
} catch (InterruptedException
e) {
}
System.out.println(threadLocal.get());
}
}
thread1.start();
thread2.start();
Concurrency
Parallelism