java concurrency and asynchronous

48
Java Concurrency and Asynchronous Lifan Yang [email protected] 2014/6/6

Upload: lifan-yang

Post on 02-Jul-2015

323 views

Category:

Engineering


2 download

DESCRIPTION

Introduce Java concurrency and asynchronous programming

TRANSCRIPT

Page 1: Java Concurrency and Asynchronous

Java Concurrency and

Asynchronous

Lifan Yang

[email protected]

2014/6/6

Page 2: Java Concurrency and Asynchronous

Agenda

● Fundamentals: JMM, volatile, sychronized,

wait and notify

● JUC: Thread Pool, Concurrent Collections,

Sychronizers

● Cancellation & Shutdown

● Java 6, 7 and 8

● Asynchronous Programming

Page 3: Java Concurrency and Asynchronous

Preliminary

● Junior programmers think Java concurrency

programming is difficult.

● Intermediate programmers think Java concurrency

programming is easy.

● Senior programmers think Java concurrecy is difficult.

Page 4: Java Concurrency and Asynchronous

Why we need concurrency programming?

1. Multi-core processors

2. IO

3. Quicker response

Page 5: Java Concurrency and Asynchronous

Agenda

● Fundamentals: JMM, volatile, sychronized,

wait and notify

● JUC: Thread Pool, Concurrent Collections,

Sychronizers

● Cancellation & Shutdown

● Java 6, 7 and 8

● Asynchronous Programming

Page 6: Java Concurrency and Asynchronous

Java Memory Model

Page 7: Java Concurrency and Asynchronous

An example

class DmaStatusChecker implements Runnable {

public void run() {

if (requestDmaStatusApiSuccess()) {

dmaManager.dmaRunning = true;

} else {

dmaManager.dmaRunning = false;

}

}

}

class DmaManager {

private boolean dmaRunning;

public boolean isDmaRunnin() {

return this.dmaRunning;

}

}

Any problems?

Page 8: Java Concurrency and Asynchronous

volatile version

class DmaManager {

private volatile boolean dmaRunning;

public boolean isDmaRunnin() {

return this.dmaRunning;

}

}

Page 9: Java Concurrency and Asynchronous

Why “volatile” is necessary?

1. Memory visibility

2. Instrument reordering

Page 10: Java Concurrency and Asynchronous

Reorder

class ReorderExample {

int a = 0;

boolean flag = false;

public void writer() {

a = 1; //1

flag = true; //2

}

Public void reader() {

if (flag) { //3

int i = a * a; //4

// ......

}

}

}

The Java Memory Model

Page 11: Java Concurrency and Asynchronous

Atomic

For example, “i++”. It is a composite operation. “volatile”

keywords cannot make “i++” to be atomic.

i++ => 1. read

2. plus

3. write

Page 13: Java Concurrency and Asynchronous

Thread cooperate: wait, notify and notifyAll

● Question: What are differences between notify and

notifyAll?

● Quesiton: In the producer/consumer model, could both

producers and consumers are waiting?

● Question: When should use notify? When should use

notifyAll?

Page 14: Java Concurrency and Asynchronous

Agenda

● Fundamentals: JMM, volatile, sychronized,

wait and notify

● JUC: Thread Pool, Concurrent Collections,

Sychronizers

● Cancellation & Shutdown

● Java 6, 7 and 8

● Asynchronous Programming

Page 15: Java Concurrency and Asynchronous

Shortcomings before Java 5

● Only ONE condition queue, no matter how many

condition predicates.

● No thread pool, create a thread is resource consumed.

● Synchronized collections are bad performanced.

● Lack concurrent collections and tools with more

features.

Page 16: Java Concurrency and Asynchronous

Thread Pool

The constructor of ThreadPoolExecutor

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,

BlockingQueue<Runnable> workQueue)

So is the following sample to create a Thread Pool correct?

new ThreadPoolExecutor(1, 10, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>());

Page 17: Java Concurrency and Asynchronous

Concurrent Collection

Page 18: Java Concurrency and Asynchronous

Sychronizers

CountDownLatch: countDown(), await()

CyclicBarrier: await()

Phaser: register(), arriveAndAwaitAdvance(),

arriveAndDeregister()

Semaphore: acquire()

Exchanger: exchange(V x)

Page 19: Java Concurrency and Asynchronous

CAS

CPU instrument: Compare and Swap

Compare and Set:int old;

int new;

do {

old = value.get();

new = doSomeCalcBasedOn(old)

while (value.compareAndSwap(old, new));

AbstractQueuedSynchronizer

Page 20: Java Concurrency and Asynchronous

Agenda

● Fundamentals: JMM, volatile, sychronized,

wait and notify

● JUC: Thread Pool, Concurrent Collections,

Sychronizers

● Cancellation & Shutdown

● Java 6, 7 and 8

● Asynchronous Programming

Page 21: Java Concurrency and Asynchronous

Interruption

The most common thing we know about the

interruption is

InterruptedException

Page 22: Java Concurrency and Asynchronous

About InterruptedException

try {

new Object().wait();

Thread.sleep(1000);

Object element = blockingQueue.take();

// Other blocked methods.

} catch(InterruptedException e) {

// This means the current thread has been interrupted.

// Sometimes we do not need to handle it.

}

So when we do not invoke a blocked method, how to know the current

thread is interrupted?

Page 23: Java Concurrency and Asynchronous

Two methods

Class “Thread” has two similar methods to know whether the current

thread is interrupted:

Modifier and Type Class and Description

static boolean interrupted()

Tests whether the current thread has been interrupted.

boolean isInterrupted()

Tests whether this thread has been interrupted.

Page 24: Java Concurrency and Asynchronous

Propogate the interruption

Page 25: Java Concurrency and Asynchronous

Why?

class AService {

public void aBizMethod() {

try {

Thread.sleep(1000);

} catch(InterruptedException e) {

// You think do nothing is ok.

}

}

}

class MyRunnable implements Runnable {

public void run() {

new AService().aBizMethod();

try {

Object item = blockingQueue.take()

// Process item

} catch(InterruptedException e) {

// do nothing

}

}

}

Page 26: Java Concurrency and Asynchronous

How?

1. Re-throw InterruptionException

2. Recover the interruption state with

Thread.currentThread().interrupt()

Page 27: Java Concurrency and Asynchronous

Cancel a Task in the Thread Pool

Cancel with Future:

Modifier and Type Method and Description

boolean cancel(boolean mayInterruptIfRunning)

Attempts to cancel execution of this task.

Page 28: Java Concurrency and Asynchronous

Shutdown a Thread Pool

Modifier and Type Method and Description

void shutdown()

Initiates an orderly shutdown in which previously submitted

tasks are executed, but no new tasks will be accepted.

List<Runnable> shutdownNow()

Attempts to stop all actively executing tasks, halts the

processing of waiting tasks, and returns a list of the tasks

that were awaiting execution.

boolean awaitTermination(long timeout, TimeUnit unit)

Blocks until all tasks have completed execution after a

shutdown request, or the timeout occurs, or the current

thread is interrupted, whichever happens first.

Page 29: Java Concurrency and Asynchronous

Agenda

● Fundamentals: JMM, volatile, sychronized,

wait and notify

● JUC: Thread Pool, Concurrent Collections,

Sychronizers

● Cancellation & Shutdown

● Java 6, 7 and 8

● Asynchronous Programming

Page 30: Java Concurrency and Asynchronous

Java 6, 7

Java 6ConcurrentSkipListMap

Java 7ForkJoinPool, RecursiveAction, RecursiveTask

LinkedTransferQueue

Page 31: Java Concurrency and Asynchronous

Java 8

Class CompletableFuture<T>: A Future that may be explicitly completed (setting its value and status), and may be

used as a CompletionStage, supporting dependent functions and actions that trigger upon its completion.

Class CountedCompleter<T>: A ForkJoinTask with a completion action performed when triggered and there are no

remaining pending actions.

DoubleAccumulator: One or more variables that together maintain a running double value updated using a supplied

function.

DoubleAdder: One or more variables that together maintain an initially zero double sum.

LongAccumulator: One or more variables that together maintain a running long value updated using a supplied

function.

LongAdder: One or more variables that together maintain an initially zero long sum.

A new StampedLock class adds a capability-based lock with three modes for controlling read/write access (writing,

reading, and optimistic reading). This class also supports methods that conditionally provide conversions across the

three modes.

Page 32: Java Concurrency and Asynchronous

Agenda

● Fundamentals: JMM, volatile, sychronized,

wait and notify

● JUC: Thread Pool, Concurrent Collections,

Sychronizers

● Cancellation & Shutdown

● Java 6, 7 and 8

● Asynchronous Programming

Page 33: Java Concurrency and Asynchronous

IO: Block, Reactor and Proactor

Block: Take a thread -> Connect -> Read -> Process

Reactor: Connect -> When connected, notify to take a thread -> Read -> Process

Proactor: Connect -> Read -> When finish read, notify to take a thread -> Process

Page 34: Java Concurrency and Asynchronous

Asynchronous Programming

Page 35: Java Concurrency and Asynchronous

Synchronous Style

function getUserEvents(request, response) {

var facebook_id = request.param('facebook_id');

try {

var user = db.users.findOne({fb_id:facebook_id});

var events = db.events.find({user_id:user.id});

response.write(events);

} catch(err) {

response.status(500).send(err);

}

}

Page 36: Java Concurrency and Asynchronous

Asynchronous Style (Callback)

function getUserEvents(request,response) {

var returnEvents = function(err, events) {

if (err)

respone.status(500).send(err);

response.write(events);

});

var givenUserFindAndReturnEvents = function(err,user) {

if (err) respone.status(500).send(err);

db.events.find({user_id:user.id}, returnEvents);

};

var findUserAndReturnEvents = function() {

var facebook_id = request.param('facebook_id');

db.users.findOne({fb_id:facebook_id}, givenUserFindAndReturnEvents);

}

findUserAndReturnEvents();

}

Page 37: Java Concurrency and Asynchronous

Synchronous Call

Page 38: Java Concurrency and Asynchronous

Reactive Programming

Iterator<T> (Pull) Observer<T> (Push)

Next T next() void onNext(T t)

Success boolean hasNext() void onCompleted()

Error Throw an exception on next()

void onError(Throwable e)

Stacks: .Net Reactive Extension, Netflix RxJava

Page 39: Java Concurrency and Asynchronous

Asynchronous Call

Page 40: Java Concurrency and Asynchronous

Callback Troubles

Page 41: Java Concurrency and Asynchronous

Akka

Based “Actor model”, written with Scala

public class Greeter extends UntypedActor {

public void onReceive(Object message) {

String greeting = "";

if (message instanceof WhoToGreet)

greeting = "hello, " + ((WhoToGreet) message).who;

else if (message instanceof Greet)

// Send the current greeting back to the sender

getSender().tell(new Greeting(greeting), getSelf());

else unhandled(message);

}

}

Page 42: Java Concurrency and Asynchronous

Spring Reactor

final Environment env = new Environment();

// Reactors are created using a ReactorSpec obtained via factory method

Reactor reactor = Reactors.reactor().env(env).get();

// Register a processor on an event.

reactor.on($("topic"), new Consumer<Event<Message>>() { ... });

// if you don't like the $, use the `object()` method

reactor.on(Selectors.object("topic"), new Consumer<Event<Message>>() { ... });

// Fire the event.

Message msg = msgService.nextMessage();

reactor.notify("topic", Event.wrap(msg));

Page 43: Java Concurrency and Asynchronous

Node.js

Page 44: Java Concurrency and Asynchronous

Servlet Async

@WebServlet(urlPatterns={"/asyncservlet"}, asyncSupported=true)

public class AsyncServlet extends HttpServlet {

@Override

public void doGet(HttpServletRequest request, HttpServletResponse response) {

response.setContentType("text/html;charset=UTF-8");

final AsyncContext acontext = request.startAsync();

acontext.start(() -> {

String param = acontext.getRequest().getParameter("param");

String result = resource.process(param);

HttpServletResponse response = acontext.getResponse();

/* ... print to the response ... */

acontext.complete();

});

}

}

Page 45: Java Concurrency and Asynchronous

Spring MVC Async

@Controller

@RequestMapping("/async/callable")

public class CallableController {

@RequestMapping("/response-body")

public @ResponseBody Callable<String> callable() {

return new Callable<String>() {

@Override

public String call() throws Exception {

Thread.sleep(2000);

return "Callable result";

}

};

}

}

Page 46: Java Concurrency and Asynchronous

Resources

并发编程网

Page 47: Java Concurrency and Asynchronous

Q & A

Page 48: Java Concurrency and Asynchronous

Thanks