Presentation is loading. Please wait.

Presentation is loading. Please wait.

Coordination aspect Review of AOP Summary of threads in Java

Similar presentations


Presentation on theme: "Coordination aspect Review of AOP Summary of threads in Java"— Presentation transcript:

1 Coordination aspect Review of AOP Summary of threads in Java
COOL (COOrdination Language) Design decisions Implementation at Xerox PARC and for Demeter/Java 5/21/2019 AOO / Demeter / NU

2 Quote taken from Gregor Kiczales’ talk: www.parc.xerox.com/aop
“To my taste the main characteristic of intelligent thinking is that one is willing and able to study in depth an aspect of one's subject matter in isolation, for the sake of its own consistency, all the time knowing that one is occupying oneself with only one of the aspects. ... Quote taken from Gregor Kiczales’ talk: these next nine slides aren’t part of the talk per-se, they are part of the setup to it. before the talk starts, the slides are shown on the screen, going from one to the next in a loop. the purpose is to set the theme for people, of separation of concerns, of what that is about, etc. I want to make clear that it is an old idea, that it is not specific to the world of software, that there are different ways to do it… - Dijkstra, A discipline of programming, 1976 last chapter, In retrospect 5/21/2019 AOO / Demeter / NU

3 A few more viewgraphs taken from Gregor Kiczales’ talk
Unfortunately, I cannot post the PowerPoint source of those viewgraphs. 5/21/2019 AOO / Demeter / NU

4 the goal is a clear separation of concerns
we want: natural decomposition concerns to be cleanly localized handling of them to be explicit in both design and implementation breaking a problem down into smaller sub-problems and then implementing those is nice, but it isn’t enough. we want more, much more: we want what we call a “clean, principled separation of concerns”. When we say that, we mean that - we want the natural concerns of the problem — in the form that is most natural to think about them — to be cleanly separated. - we’d like each to be entirely contained in one module. - more than that we want the design decisions to be explicit - more than that we want this separation to exist in both the design and the implementation 5/21/2019 AOO / Demeter / NU

5 achieving this requires...
synergy among problem structure and design concepts and language mechanisms “natural design” “the program looks like the design” it seems to me that achieving this requires two synergies: requires that those concepts fit the concerns in the system in a natural way requires that the language mechanisms fit those concepts in a natural way these lead to two synergies… which in turn gets us what we want ——— old stuff below here when the design philosophy and the implementation mechanisms work really well together, you get this synergistic duality sort of effect, where the actual program looks like (is isomorphic to) the design. each independent concern is addressed by an independent program component. and the composition of the program units matches the decomposition in the design 5/21/2019 AOO / Demeter / NU

6 Cross-cutting of components and aspects
better program ordinary program structure-shy functionality Components structure Aspect 1 avoid tangled programs AOP synchronization Aspect 2 5/21/2019 AOO / Demeter / NU

7 Demeter structure structure-shy structure-shy behavior communication
compiler/ weaver structure-shy communication structure-shy behavior To many people it comes as a surprise that structure can be factored out into a separate aspect. structure-shy communication AOP: Demeter application structure-shy object description synchronization 5/21/2019 AOO / Demeter / NU

8 Aspect-Oriented Programming
components and aspect descriptions High-level view, implementation may be different Source Code (tangled code) From Gregor: maybe source code should say: intermediate source code add: picture of a preprocessor style implementation of an AOP system not all AOP systems will be preprocessor like. It is reasonable to expect that in the future the better ones won’t be this is a picture of what AOP is equivalent to, not necessarily how it works. general AOP weaver (compile- time) 5/21/2019 AOO / Demeter / NU

9 Technology Evolution Object-Oriented Programming
Law of Demeter dilemma Tangled structure/behavior Adaptive Programming Other tangled code Aspect-Oriented Programming 5/21/2019 AOO / Demeter / NU

10 Components/Aspects of Demeter
Functionality (structure-shy) Traversal (Traversal Strategies) Functionality Modification (Visitors) Structure (UML class diagrams) Description (annotated UML class diagrams, class dictionaries) Synchronization more details on Demeter aspects 5/21/2019 AOO / Demeter / NU

11 Threads ! Thread 1 Thread 2 5/21/2019 AOO / Demeter / NU

12 Coordination aspect Put coordination code about thread synchronization in one place. Threads are synchronized through methods. Method synchronization Exclusion sets Method managers 5/21/2019 AOO / Demeter / NU

13 Java Threads Thread class in Standard Java libraries
Thread worker = new Thread() start method spawns a new thread of control based on Thread object. start invokes the threads run method: active thread 5/21/2019 AOO / Demeter / NU

14 Java Threads synchronized method: locks object. A thread invoking a synchronized method on the same object must wait until lock released. Mutual exclusion of two threads. class Account { synchronized double getBalance() { return balance;} synchronized void deposit(double a) { balance += a;} } 5/21/2019 AOO / Demeter / NU

15 Java Threads synchronized statements synchronized (expr) statement
lock an object without invoking a synchronized method expr must produce an object to lock 5/21/2019 AOO / Demeter / NU

16 Java Threads communication between threads with wait and notify (defined in class Object). cliché: synchronized void doWhenCondition() { while (!condition) wait(); do_it(); } 5/21/2019 AOO / Demeter / NU

17 Java Threads notify: after change of data that some other thread is waiting on synchronized void changeCondition(){ // change some value notifyall(); // wakes all waiting threads } 5/21/2019 AOO / Demeter / NU

18 Problem with synchronization code: it is tangled with component code
class BoundedBuffer { Object[] array; int putPtr = 0, takePtr = 0; int usedSlots = 0; BoundedBuffer(int capacity){ array = new Object[capacity]; } 5/21/2019 AOO / Demeter / NU

19 Tangling synchronized void put(Object o) {
while (usedSlots == array.length) { try { wait(); } catch (InterruptedException e) {}; } array[putPtr] = o; putPtr = (putPtr +1 ) % array.length; if (usedSlots==0) notifyall(); usedSlots++; // if (usedSlots++==0) notifyall(); The if (usedSlots == 0) is used for efficiency reasons so that other threads are only notified if the buffer switches from empty to nonempty 5/21/2019 AOO / Demeter / NU

20 Solution: tease apart basics and synchronization
write core behavior of buffer write coordinator which deals with synchronization use weaver which combines them together simpler code replace synchronized, wait, notify and notifyall by coordinators 5/21/2019 AOO / Demeter / NU

21 With coordinator: basics
Using Demeter/Java, *.beh file With coordinator: basics BoundedBuffer { public void put (Object o) array[putPtr] = o; putPtr = (putPtr+1)%array.length; public Object take() Object old = array[takePtr]; array[takePtr] = null; takePtr = (takePtr+1)%array.length; usedSlots--; return 5/21/2019 AOO / Demeter / NU

22 Coordinator Using Demeter/COOL, put into *.cool file
coordinator BoundedBuffer { selfex put, take; mutex {put, take} condition empty=true, full=false; exclusion sets coordinator variables 5/21/2019 AOO / Demeter / NU

23 Coordinator method managers with requires clauses and entry/exit clauses put requires (!full) { on exit {empty=false; if (usedSlots==array.length) full=true; }} take requires (!empty) { on exit {full=false; if (usedSlots==0) empty=true; }} } 5/21/2019 AOO / Demeter / NU

24 exclusion sets selfex A.f,B.g; mutex {g,h,i} mutex {f,k,l}
only one thread can call a selfex method A.f and B.g may run simultaneously. mutex {g,h,i} mutex {f,k,l} if a thread calls a method in a mutex set, no other thread may call a method in the same mutex set. 5/21/2019 AOO / Demeter / NU

25 Multi-class coordination supported
coordinator A, B { selfex A.put, B.take; mutex {B.put, A.take} condition empty=true, full=false; ... 5/21/2019 AOO / Demeter / NU

26 Design decisions behind COOL
The smallest unit of synchronization is the method. The provider of a service defines the synchronization (monitor approach). Coordination is contained within one coordinator. Association from object to coordinator is static. 5/21/2019 AOO / Demeter / NU

27 Design decisions behind COOL
Deals with thread synchronization within each execution space. No distributed synchronization. Coordinators can access the objects’ state, but they can only modify their own state. Synchronization does not “disturb” objects. Currently a design rule not checked by implementation. 5/21/2019 AOO / Demeter / NU

28 COOL Provides means for dealing with mutual exclusion of threads, synchronization state, guarded suspension and notification coordinator ! Thread 1 Thread 2 5/21/2019 AOO / Demeter / NU

29 COOL Identifies “good” abstractions for coordinating the execution of OO programs coordination, not modification of the objects mutual exclusion: sets of methods preconditions on methods coordination state (history-sensitive schemes) state transitions on coordination 5/21/2019 AOO / Demeter / NU

30 COOL Shape plain Java public class Shape { coordinator Shape {
protected double x_ = 0.0; protected double y_ = 0.0; protected double width_ = 0.0; protected double height_ = 0.0; double x() { return x_(); } double y() { return y_(); } double width(){ return width_(); } double height(){ return height_(); void adjustLocation() { x_ = longCalculation1(); y_ = longCalculation2(); void adjustDimensions() { width_ = longCalculation3(); height_ = longCalculation4(); coordinator Shape { selfex {adjustLocation, adjustDimensions} mutex {adjustLocation,x} mutex {adjustLocation,y} mutex {adjustDimensions, width} height} } 5/21/2019 AOO / Demeter / NU

31 Programming with COOL Protocol object/coordinator: 1
1: method invocation coordinator 2 2: request presented to the coordinator 3 3: coordinator checks synchronization state, eventually suspending thread; when thread can proceed,coordinator performs “on_entry” actions 7 7: coordinator performs “on_exit” actions 8 8: method returns 4 4: request proceeds to the object 6 6: return is presented to coordinator 5 5: method execution m() {…} object 5/21/2019 AOO / Demeter / NU

32 COOL View of Classes Stronger visibility: Limited actions:
coordinator can access: all methods and variables of its classes, independent of access control all non-private methods and variables of their superclasses Limited actions: only read variables, not modify them only coordinate methods, not invoke them 5/21/2019 AOO / Demeter / NU

33 Programming with COOL Implementing COOL Implementation Semantics
Xerox PARC Implemention object coordinator m() {…} 1 2 4 5 6 3 8 Implementation 7 Implementing COOL Programming with COOL coordinator 3 7 8 2 4 6 5 m() {…} 1 object Semantics 5/21/2019 AOO / Demeter / NU

34 COOL public class BoundedBuffer { coordinator BoundedBuffer {
private Object array[]; private int putPtr = 0, takePtr = 0; private int usedSlots = 0; public BoundedBuffer(int capcty){ array = new Object[capcty]; } public void put(Object o) { array[putPtr] = o; putPtr = (putPtr+1)%array.length; usedSlots++; public Object take() { Object old = array[takePtr]; array[takePtr] = null; takePtr = (takePtr+1)%array.length; usedSlots--; return old; coordinator BoundedBuffer { selfex {put, take} mutex {put, take}; boolean put requires { on exit empty = false; if (usedSlots==array.length) full = true; @) } take requires (!empty){ full = false; if (usedSlots == 0) empty = true; 5/21/2019 AOO / Demeter / NU

35 Implementing COOL BoundedBuffer BoundedBufferCoord 2 5 3 4 6 1 7 8
_dcoord // rest of the variables protected void _d_put(Object o){ //implementation code } public void put(Object o) { _dcoord.enter_put(this); try { _d_put(o); } finally { _dcoord.exit_put(this); protected Object _d_take() { public Object take() { //similar to put // variable next page synchronized void enter_put(BoundedBuffer o){ // ... } exit_put(BoundedBuffer o) { enter_take(BoundedBuffer o){ exit_take(BoundedBuffer o) { 2 4 5 3 1 6 7 8 5/21/2019 AOO / Demeter / NU

36 Implementing COOL class BoundedBufferCoord {
MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots()==o._dget_size()) full=true; notifyAll(); ... 5/21/2019 AOO / Demeter / NU

37 Implementing COOL to keep track of method execution state
class BoundedBufferCoord { MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots() == o._dget_size()) full = true; notifyAll(); ... 5/21/2019 AOO / Demeter / NU

38 One class to support COOL
class MethodState { int depth = 0; Vector t1 = new Vector(); final public boolean isBusyByOther() { if (depth > 0 && !t1.contains(Thread.currentThread())) return true; else return false;} final public void in() { depth++; t1.addElement(Thread.currentThread());} final public void out() { depth--; …} 5/21/2019 AOO / Demeter / NU

39 Implementing COOL coordination vars class BoundedBufferCoord {
MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots()==o._dget_size()) full=true; notifyAll(); ... coordination vars 5/21/2019 AOO / Demeter / NU

40 Implementing COOL conditions for waiting class BoundedBufferCoord {
MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots() == o._dget_size()) full = true; notifyAll(); ... Implementing COOL conditions for waiting 5/21/2019 AOO / Demeter / NU

41 Implementing COOL update method state class BoundedBufferCoord {
MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots() == o._dget_size()) full = true; notifyAll(); ... update method state 5/21/2019 AOO / Demeter / NU

42 Implementing COOL update method state class BoundedBufferCoord {
MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots() == o._dget_size()) full = true; notifyAll(); ... update method state 5/21/2019 AOO / Demeter / NU

43 Implementing COOL on_exit statements class BoundedBufferCoord {
MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots()==o._dget_size()) full=true; notifyAll(); ... on_exit statements 5/21/2019 AOO / Demeter / NU

44 Implementing COOL notify state change class BoundedBufferCoord {
MethState put = new MethState(); MethState take = new MethState(); boolean empty = true, full = false; public synchronized void enter_put(BoundedBuffer o) { while (put.isBusyByOtherThread() || take.isBusyByOtherThread() || full) { try { wait(); } catch (InterruptedException e) {} } put.in(); public synchronized void exit_put(BoundedBuffer o) { put.out(); empty = false; if (o._dget_usedlots()==o._dget_size()) full=true; notifyAll(); ... Implementing COOL notify state change 5/21/2019 AOO / Demeter / NU

45 Acknowledgments Many of the viewgraphs prepared by Crista Lopes for her Ph.D. work supported by Xerox PARC. Implementation of COOL for Demeter/Java by Josh Marshall. Integration into Demeter/Java with Doug Orleans. ECOOP ‘94 paper on synchronization patterns by Lopes/Lieberherr. 5/21/2019 AOO / Demeter / NU


Download ppt "Coordination aspect Review of AOP Summary of threads in Java"

Similar presentations


Ads by Google