oh what a tangled web we weave...... when first to thread we do conceive
Post on 21-Dec-2015
215 Views
Preview:
TRANSCRIPT
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
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
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
The truth of synchronized•Java synchronized keyword just means:
get lock before proceeding; release lock when done
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];
}}
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;
}}
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 (*)
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
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;
}
Who owns the lock?The memory picture:
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; }
}
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)
Who owns the lock?The memory picture:
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; }}
}
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
Who owns the lock?The memory picture:
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; } }
}
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)
Who owns the lock?The memory picture:
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; } }
}
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!
Who owns the lock?The memory picture:
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; }
}
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.
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; }}
}
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.
Who owns the lock?The memory picture:
???
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
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; }
}
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.
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!!!
Who owns the lock?•Consider:
WhoOwnsTheLock foo=new WhoOwnsTheLock();WhoOwnsTheLock bar=new WhoOwnsTheLock();
Who owns the lock?
Who owns the lock?•Consider:
WhoOwnsTheLock foo=new WhoOwnsTheLock();WhoOwnsTheLock bar=new WhoOwnsTheLock();
// in thread 0foo.getY0();
// in thread 1bar.getY0();
Who owns the lock?th
read
0
sync
h w
/ thi
s
lock
Who owns the lock?th
read
0
sync
h w
/ thi
s
lock
& thread 1
synch w/ this
one
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;}
}
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!)
Who owns the lock?
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; }}
}
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...
Who owns the lock?
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();}
}
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)
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();}
}
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.
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(); } } }}
Who owns the lock?
Who owns the lock?
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; } } }
}
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
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)
top related