Top Banner
Oh what a tangled web we weave... ... when first to thread we do conceive.
53
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: Oh what a tangled web we weave...... when first to thread we do conceive.

Oh what a tangled web we weave...... when first to thread we do conceive.

Page 2: Oh what a tangled web we weave...... when first to thread we do conceive.

History•Last time

•Threads & synchronization

•This time:

•Team tips

•Synchronization, cont’d.

•Design exercise

Page 3: Oh what a tangled web we weave...... when first to thread we do conceive.

Team tip: code ownership•Who “owns” a module? Who is responsible for

it?

•Model 1: Strong individual ownership

•One person is exclusive owner of each module

+Knows it inside out

+Can easily fix bugs, etc.

+Clear-cut lines of responsibility

+Each developer has limited responsibility

xAll changes have to pass through one person

xCan be a serious bottleneck

Page 4: Oh what a tangled web we weave...... when first to thread we do conceive.

Team tip: code ownership•Loose ownership model

•Whole code base is “owned” by group

•Indivs may work primarily on one aspect, but anybody has rights to change anything

+Fewer bottlenecks

+More responsive to individual needs

xIndividuals have to be generalists, not specialists

xLess familiarity ⇒ very easy to introduce bugs

•Esp. integration bugs

•Regression testing critical

Page 5: Oh what a tangled web we weave...... when first to thread we do conceive.

The truth of synchronized•Java synchronized keyword just means:

get lock before proceeding; release lock when done

Page 6: Oh what a tangled web we weave...... when first to thread we do conceive.

The truth of synchronizedpublic class Panopticon {

private double[] _data;

public synchronized void set(int idx, double v) {_data[idx]=v;

}

public synchronized double get(int idx) {return _data[idx];

}}

Page 7: Oh what a tangled web we weave...... when first to thread we do conceive.

The truth of synchronizedpublic class Panopticon {

private double[] _data;hidden Object _lockID_=null;public void set(int idx, double v) {

while (!_testAndSet_(_lockID_==null || _lockID==this,this));_data[idx]=v;_atomicSet_(_lockID,null);

}public double get(int idx) {

while (!_testAndSet_(_lockID_==null || _lockID_==this,this));int result=_data[idx];_atomicSet_(_lockID_,null);return result;

}}

Page 8: Oh what a tangled web we weave...... when first to thread we do conceive.

The truth of synchronized•Java synchronized keyword just means:

get lock before proceeding; release lock when done

•synchronized method: only one thread can execute this method at a time (*)

•synchronized block: only one thread can execute this block at a time (*)

Page 9: Oh what a tangled web we weave...... when first to thread we do conceive.

Where is the lock?•Caveat: synchronized methods/blocks are only mutex with respect to a single lock

•Have to make sure that all threads are using the same lock

•Where does the lock variable live?

•non-static synchronized methods: lives on the object instance

•static synchronized methods: lives on the class variable

•synchronized block: lives on the object named in the argument

Page 10: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

}

Page 11: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?The memory picture:

Page 12: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }

}

Page 13: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }

}

Answer: “this” owns it (object on which getX0() is being called)

Page 14: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?The memory picture:

Page 15: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }public List getX1() { synchronized(x){return x; }}

}

Page 16: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }public List getX1() { synchronized(x){return x; }}

}

Answer: x itself owns the lock

Page 17: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?The memory picture:

Page 18: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }public List getX1() { synchronized(x){return x; }}public List getX2() {

synchronized(this) { return x; } }

}

Page 19: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }public List getX1() { synchronized(x){return x; }}public List getX2() {

synchronized(this) { return x; } }

}

Again, “this” owns it (duh)

Page 20: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?The memory picture:

Page 21: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }public List getX1() { synchronized(x){return x; }}public List getX2() {

synchronized(this) { return x; } }public synchronized List getX3() {

synchronized(x) { return x; } }

}

Page 22: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getX0() { return x; }public List getX1() { synchronized(x){return x; }}public List getX2() {

synchronized(this) { return x; } }public synchronized List getX3() {

synchronized(x) { return x; } }

}

Trick question! Both locks (this and x) have tobe acquired!

Page 23: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?The memory picture:

Page 24: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getA0() { return a; }

}

Page 25: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getA0() { return a; }

}

Same old, same old. “this” has the lock.

Page 26: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getA0() { return a; }public int getA1() { synchronized(a){ return a; }}

}

Page 27: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getA0() { return a; }public int getA1() { synchronized(a){ return a; }}

}

Another trick question! a is atomic -- it’s notan Object, and doesn’t have hidden state.

Page 28: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?The memory picture:

???

Page 29: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?•Error you get from trying to synchronize on an atomic field:

WhoOwnsTheLock.java:12: incompatible typesfound : intrequired: java.lang.Object public int getA1() { synchronized(a) { return a; } } ^1 error

Page 30: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getY0() { return y; }

}

Page 31: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getY0() { return y; }

}

Again, “this” owns the lock.

Page 32: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getY0() { return y; }

}

Again, “this” owns the lock.Danger Will Robinson! Can have multiple accessto y!!!

Page 33: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?•Consider:

WhoOwnsTheLock foo=new WhoOwnsTheLock();WhoOwnsTheLock bar=new WhoOwnsTheLock();

Page 34: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?

Page 35: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?•Consider:

WhoOwnsTheLock foo=new WhoOwnsTheLock();WhoOwnsTheLock bar=new WhoOwnsTheLock();

// in thread 0foo.getY0();

// in thread 1bar.getY0();

Page 36: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?th

read

0

sync

h w

/ thi

s

lock

Page 37: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?th

read

0

sync

h w

/ thi

s

lock

& thread 1

synch w/ this

one

Page 38: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getY0() { return y; }public static synchronized List getY1() {

return y;}

}

Page 39: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getY0() { return y; }public static synchronized List getY1() {

return y;}

}

Remember: “static”==“associated with class” (i.e.,class object).So this is synchronized on the class object. No more conflict. (yay!)

Page 40: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?

Page 41: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getY0() { return y; }public static synchronized List getY1() {

return y;}public static List getY2() {

synchronized(y) { return y; }}

}

Page 42: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized List getY0() { return y; }public static synchronized List getY1() {

return y;}public static List getY2() {

synchronized(y) { return y; }}

}

Effectively, just as good as previous version...

Page 43: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?

Page 44: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getXY0() { return x.size()+y.size();}

}

Page 45: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getXY0() { return x.size()+y.size();}

}

Synchronized on “this”, but can have concurrent access via y (x is safe)

Page 46: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getXY0() { return x.size()+y.size();}public static synchronized int getXY1() {

return x.size()+y.size();}

}

Page 47: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getXY0() { return x.size()+y.size();}public static synchronized int getXY1() {

return x.size()+y.size();}

}

Same problem, but in reverse -- y is safe, but can have multi-access to x.

Page 48: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public synchronized int getXY0() { return x.size()+y.size();}public static synchronized int getXY1() {

return x.size()+y.size();}public int getXY2() {

synchronized(this) { // or on x itselfsynchronized(y) {

return x.size()+y.size(); } } }}

Page 49: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?

Page 50: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?

Page 51: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public int getAB0() {synchronized(this) {

synhronized(b) { // oh oh... b is atomicreturn a+b; } } }

}

Page 52: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public int getAB0() {synchronized(this) {

synhronized(y) {return a+b; } } }

}

Answer 1: synchronize on something “near” b (i.e., something else static) that isn’t, itself, atomic.

Sometimes introduce spurious “Object” just for this

Page 53: Oh what a tangled web we weave...... when first to thread we do conceive.

Who owns the lock?public class WhoOwnsTheLock {

private List x=new LinkedList();private static List y=new LinkedList();private int a=3;private static int b=42;

public static synchronized int getAB1() {synchronized(this) { return a+b; } }

}

Answer 2: synchronize on class object (via “static synchronized” method declaration)