android concurrency

Post on 10-Jul-2015

529 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Android Concurrency

and beyond

novikov.ruslan@gmail.com

Why is concurrency in Android important?

• Until pretty recently, real, concurrent execution happened only on expensive server hardware

• – Android already runs on multi-core devices.

• – It will get worse: Moore's law is now about number, not speed, of CPUs

• – Android devices actually need to do multiple things at the same time: Real Time Computing

Android Puts Concurrency in your Face

• The UI is single threaded but will not tolerate long running, synchronous tasks

• IPC (Binder) calls appear on non-UI threads and you can't use the UI from a non-UI thread (a topic for another day...)

Java Concurrency Primitives

• Language level constructs – Synchronized – Thread/Runnable • Concurrency library (java.util.concurrent) – Executor/Callable/Future – Atomics • All are available in Android – Low level Java tools are really low level. If you find yourself using them you might want to review your architecture • – Android Concurrency tools are firmly based on the

concurrency library (java.util.concurrent)

Java Memory Model

Compiler Optimizations

Is Vector Really so Thread Safe?

Synchronized Collections

Concurrent Collections

• CopyOnWriteArrayList

• ConcurrentHashMap

• BlockingQueue

• Vector

• Hashtable

• Collections.synchronizedMap()

• …

Executor

• Executor

• ExecutorService

• ScheduledExecutorService

• Future

• Callable

• Executors

ExecutorService Executor

Task submission:

executorService.submit(MyTask);

executorService.invokeAll(Collection<Tasks>);

executorService.invokeAny(Collection<Tasks>);

Lifecycle management:

executorService.shutdown();

executorService.shutdownNow();

Lifecycle observation:

executorService.isShutdown();

executorService.isTerminated();

executorService.awaitTermination();

Running Shutting

Down Terminated

shutdown()

Task / Execution Environment Executor

Task: Independent unit of work executed anywhere

Runnable run()

Callable call()

Execution Environment:

Technique used to execute the task

Executor execute(Runnable)

Future future = executorService.submit(Callable);

Future isDone()

isCancelled() cancel()

Task manager/observer:

Threads on Android

UI

Android App

Linux Process

Native Threads Java Threads

BG BG BG

Android Scheduling

1. Foreground

2. Visible

3. Service

4. Background

Process level:

Android App

Android Scheduling

1. Foreground

2. Visible

3. Service

4. Background

Process level:

App A

App A

Foreground Thread Group

Background Thread Group

App B App B

> 90%

< 10%

Android Scheduling

1. Foreground

2. Visible

3. Service

4. Background

Process level:

App A

App A

Foreground Thread Group

Background Thread Group

App B App B

> 90%

< 10%

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

Activity Lifecycle

Time

Activity Component

onCreate() onDestroy() onCreate() onDestroy()

Activity Object

new() GC

Activity Object

new() GC

Activity Lifecycle

Time

Activity Component

onCreate() onDestroy() onCreate() onDestroy()

Activity Object

new()

Activity Object

new()

Start

BG

Reference

Goal

What technique shall I use for my background thread

execution?

Android Asynchronous Techniques

• HandlerThread

• AsyncTask

• Service

• IntentService

• AsyncQueryHandler

• Loader

HandlerThread

• Inherits from Thread and encapsulates a Looper-object

• Thread with a message queue and processing loop

• Handles both Message and Runnable

Running Dead t.quit() t = new HandlerThread().start();

How it works HandlerThread

Handler Thread

Create and Start

Add Process

Message Queue

1

2 3

t = new HandlerThread("BgThread"); t.start();

1 Handler h = new Handler(t.getLooper()) {

@Override

public void handleMessage(Message msg) {

//Process message

} };

2

h.sendEmptyMessage(42); 3

Handler HandlerThread

Runnable/Message submission:

Lifecycle management:

Runnable/Message removal:

removeCallbacks(Runnable);

removeMessages(Message)

post(Runnable);

postDelayed(Runnable);

postAtTime(Runnable)

postAtFrontOfQueue(Runnable);

sendMessage(Message);

sendMessageDelayed(Message);

sendMessageAtTime(Message);

sendMessageAtFrontOfQueue(Message);

AsyncTask

• Wraps Handler/Looper thread communication.

• Utilizes the Executor framework.

• Callbacks for UI operations and Background operation.

onCancelled() 4b

How it works AsyncTask

UI Thread

BG Thread

new AsyncTask.execute() 1

onPreExecute() 2

3 doInBackground()

onPostExecute() 4a

AsyncTask.cancel()

Application Global Behavior AsyncTask > Pitfalls

execute()

Queue Thread Pool

Activity

execute() Activity

execute() Service

execute() Receiver

execute() *

execute()

•Execution behavior has changed over time

AsyncTask > Pitfalls

execute() < Donut:

execute() < Honeycomb:

execute()

executeOnExecutor(Executor)

>= Honeycomb:

execute() AsyncTask > Pitfalls

<uses-sdk android:targetSdkVersion="12" />

<uses-sdk android:targetSdkVersion="13" />

“So, if I call AsyncTask.execute on Honeycomb and later my tasks will run

sequentially, right?”

“Right?!?”

“Eh, it depends…”

Possible solutions: In reverse order of appeal

• Weak Reference

• Persistent

• Cancellable

• Independent

Weak Reference

• Just make all references to the Activity weak

• Currently a “well-known” solution

• The refuge of scoundrels:

– Allows the process to continue, even when the value will be discarded

– Doesn't fix references to destroyed processes

• These are the folks who used to lazily initialize their database connections.

Independent

• What happens when firing the AT is a contract with the UI, and must complete?

• Do the simplest possible proxy to the model

• The inverse of the RESTful ContentProvider cache

Service

Time

Activity Component

onCreate() onDestroy() onCreate() onDestroy()

Service Component

BG

onCreate() onDestroy()

Intent Service

Time

IntentService Component

Intent 1 BG Intent 2 Intent 3 Intent n

stopSelf()

onCreate() onDestroy()

Good Use Cases

• Serially executed tasks decoupled from other component lifecycles.

• Off-load UI thread from BroadcastReceiver.

• REST client (ResultReceiver as callback)

IntentService

AsyncQueryHandler

• API Level 1

• Asynchronous operations on a ContentResolver

• Query

• Insert

• Delete

• Update

• Wraps a HandlerThread

How it works AsyncQueryHandler

UI Thread

BG Thread

new AsyncQueryHandler(); 1

startQuery(); startInsert(); startUpdate(); startDelete();

2

onQueryComplete(); onInsertComplete(); onUpdateComplete(); onDeleteComplete();

3

DB operations

Cons

• No cursor management

• No content observation

• No data retention on configuration changes

• Background thread can’t be forced to quit

AsyncQueryHandler

Loader

• API added in Honeycomb

• Available in compatibility package

• Load data in a background thread

• Observes data changes

• Retained on configuration changes

• Connected to the Activity and Fragment lifecycles

Basics Loader

Data Source

Loader

1 Load data in BG 2 Observe data

3 Lifecycle management 4 Retained on configuration change

Data Sources Loader

Any Data Source

Content Provider

Custom Loader

Cursor Loader

How It Works Loader

public class AndroidLoaderActivity extends ListActivity implements LoaderCallbacks<Cursor>{

SimpleCursorAdapter mAdapter;

public void onCreate(Bundle savedInstanceState) {

getLoaderManager().initLoader(0, null, this);

}

@Override

public Loader<Cursor> onCreateLoader(int id, Bundle args) {

return new CursorLoader(..., CONTENT_URI, ...);

}

@Override

public void onLoadFinished(Loader<Cursor> loader, Cursor c) {

mAdapter.swapCursor(c);

}

@Override

public void onLoaderReset(Loader<Cursor> arg0) {

mAdapter.swapCursor(null);

}

}

Used Material

• http://www.infoq.com/presentations/Concurrency-Android • http://developer.android.com/reference/android/os/Proces

s.html • http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-

133-faq.html • http://docs.oracle.com/javase/specs/jls/se7/html/jls-

17.html • https://plus.google.com/u/0/105051985738280261832/po

sts/XAZ4CeVP6DC • https://github.com/keesj/gomo/wiki/AndroidScheduling • http://stackoverflow.com/questions/7931032/android-

process-scheduling • https://www.youtube.com/watch?v=_q12gb7OwsA

novikov.ruslan@gmail.com

Thanks T

h a

n k s

top related