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

Java Concurrency and Asynchronous

Jul 02, 2015

Download

Engineering

Lifan Yang

Introduce Java concurrency and asynchronous programming
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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