MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access...

20
MobAppDev Circular Motion, Sinusoid Curves, & Application Objects Part 03: Access Synchronization Vladimir Kulyukin www.vkedco.blogspot.com

description

 

Transcript of MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access...

Page 1: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

MobAppDev

Circular Motion, Sinusoid Curves, &

Application Objects Part 03: Access Synchronization

Vladimir Kulyukin

www.vkedco.blogspot.com

Page 2: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Outline● Review

Threads Static & Non-Static Synchronization Joining threads

● Access Synchronization

Page 3: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Review

Page 4: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

How Threads Run

● Each thread starts and runs to completion● A thread finishes when its run() method finishes● A thread can never be re-started (calling start() more than

once on the same Thread object throws IllegalThreadStateException)

● The order in which the Runnable threads get to run is JVM-specific

Page 5: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

How Threads Sleep & Yield● When a Thread goes to sleep (Thread.sleep() is executed) and

wakes up, it does not start running – it becomes Runnable and may be selected to run by the JVM scheduler

● A yielding Thread (Thread.yield() is executed) yields to the Threads with the same priorities but there is no guarantee that another Thread will be chosen by the JVM scheduler – the same Thread (the one that just yielded) may be chosen to run again and again

Page 6: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

How to Synchronize in Java● Every Java Instance Object and Java Class Object has a

built-in lock● Non-static methods should synchronize on Instance Objects

(this Object)● Static methods should synchronize on Class Objects● Since there is only one lock per Object, once a Thread picks

up the lock, no other thread can enter until the first Thread finishes

Page 7: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

How to Synchronize: Blocks & Methods

// Here is an example of a synchronized block

class MySync {

public void myMethod() {

synchronized(this) {

// do some stuff here

}

}

}

// Here is an example of a synchronized method

class MySync {

public void synchronized myMethod() {

// do some stuff here

}

}

Page 8: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

How Threads Sync● Threads calling non-static synchronized methods/blocks block each

other if they synchronize on the same Instance Objects● Threads calling static synchronized methods/blocks block each other

if they synchronize on the same Class Objects● Threads executing static and non-static methods/blocks NEVER

block each other● Rule of Thumb: Be careful when mixing static and non-static

synchronization and check which Thread synchronizes on which object

Page 9: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Joining Threads

● Thread.join() is the method that allows one thread to wait until another thread completes

● th.join(): the current thread waits until thread th completes

● th.join(int wait_time): wait_time specifies the waiting period (in milliseconds) for the current thread

Page 10: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Access Synchronization

Page 11: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

When Should I Synchronize Access?

● Wherever there are concurrent threads that can access and modify the same objects or other resources, such as SQLite databases, questions of access synchronization must be addressed

● If access is not synchronized or synchronized incorrectly, objects and/or data may become inconsistent

Page 12: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Example

Write an application that starts four concurrent threads. Each thread randomly moves a small circle on the canvas. Threads can dance synchronously (one circle per time) or asynchronously (all circles move as they please)

source code is in DancingCirclesApp repo

Page 13: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Screenshots

Page 14: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Application Details: Synchronized Dance● The application creates four circle objects on a custom view's (PainterView.java)

canvas and uses four threads to randomly move four circles on the canvas● The main activity (DancingCirclesAct.java) defines an options menu with three

items: Synchronized Dance, Unsynchronized Dance, and Stop the Dance ● When the user presses Synchronized Dance, the activity starts four worker threads

with Runnables that synchronize on the PainterView object in DancingCirclesApp.java

● The configuration of the circles on the canvas of PainterView.java changes one circle at a time

● In a synchronized dance, one circle thread may usurp the CPU cycles for a while● Synchronization is implemented in the inner class SynchronizedPainterRunnable in

DancingCirclesAct.java

Page 15: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Application Details: Unsynchronized Dance● When the user selects Unsynchronized Dance, the activity starts four worker

threads with Runnables that do not synchronize on the PainterView object in DancingCirclesApp

● Therefore, the configuration of the circles on the canvas of the PainterView changes four circles at a time

● Asyncrhonization is implemented in the inner class UnsynchronizedPainterRunnable in DancingCirclesAct.java

● Note that both SychronizedPainterRunnable and UnsynchronizedPainterRunnable implement the Runnable interface

Page 16: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Access Synchronizationin

CircularMotion Application

source code is in this repo

Page 17: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Synchronizing Circular & Sinusoid Motions

● The sample synchronization principles are applied in the CircularMotion application

● The rotating circles objects are started in unsychronized threads

● The synchronization happens only when each circle is drawn on the canvas

Page 18: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Runnables that Moves Circlesclass UnsynchronizedPainterRunnable implements Runnable { Circle mCircle = null; boolean mThreadRunning = false; public UnsynchronizedPainterRunnable(Circle c) { mCircle = c; } @Override public void run() { mThreadRunning = true; while ( mThreadRunning ) { ((RotatingCircle) mCircle).move(); try { // Have the thread sleep Thread.sleep(CircularMotionMainActivity.SLEEP_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); mThreadRunning = false; } } }}

While the thread is running, the circle object stored in mCircle is cast into RotatingCircle (implemented in RotatingCircle.java)and moved (i.e., rotated a specific amount around the coordinate center on the left of the custom view). The thread then goes to sleep. This class is an inner class of CircularMotionMainActivity.java.

Page 19: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Starting Asynchronous Threadspublic class CircularMotionMainActivity extends Activity { ArrayList<Thread> mCircleThreads = null;

protected void onCreate(Bundle savedInstanceState) { mCircleThreads = new ArrayList<Thread>(); startUnsynchronizedThreads(); }

private void startUnsynchronizedThreads() { Thread th = null; for(Circle c: mPainterView.getCircles()) { th = new Thread(new UnsynchronizedPainterRunnable(c)); mCircleThreads.add(th); th.start(); }}

The main activity creates an ArrayList of Threads. The onCreate() method of the main activity starts the threads and adds them to the ArrayList of Threads.

Page 20: MobAppDev (Fall 2014): Circular Motion, Sinusoid Curves, & Application Objects: Part 03: Access Synchronization

Thread Synchronization at Drawing Timepublic void draw(Canvas canvas) { final int width = canvas.getWidth(); final int height = canvas.getHeight(); // 1. draw background rectangle that covers the entire canvas canvas.drawRect(0, 0, width, height, mBackgroundPaint); // 2. synchronize and draw synchronized (this) { this.drawXAxis(canvas); this.drawYAxis(canvas); this.drawSinusoidXAxis(canvas); this.drawSinusoidYAxis(canvas); this.drawCirclesOnCanvas(canvas); this.drawSinusoidCurves(canvas); // 3. force the canvas to redraw this.invalidate(); }}

The synchronization happens in CircularMotionPainterView.java when all circles and sinusoids are drawn.