Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] flow of execution in different threads



There have been a number of questions about determining cflow across
threads e.g. is a join point one thread in the control flow of a join point
on the thread that created me and can I pass context. Here is an example of
how to do it with read-only state. The Main class has 2 methods leaf() and
root().  The "root()" method executes "leaf()" on another thread. We want
to obtain state in "leaf()" from earlier in the control flow, in this case
an instance of the Main class, which is done using a percflow aspect and a
Hashmap. The root, lead, create and run pointcuts could be customized or
made abstract. Comments welcomed:

public class Main implements Runnable {

      private String name;

      public Main (String s) {
            this.name = s;
      }

      public static void main(String[] args) {
            Main main1 = new Main("One");
            main1.leaf();
            main1.root();

            Main main2 = new Main("Two");
            main2.leaf();
            main2.root();
      }

      public String toString () {
            return "Main[" + name + "]";
      }

      public void root () {
            System.err.println("? " + getThreadName() + " root()");
            leaf();
            create();
      }

      public void create () {
            System.err.println("> " + getThreadName() + " create()");

            Thread thread = new Thread(this);
            thread.start();
            try {
                  thread.join();
            }
            catch (InterruptedException ex) {
                  ex.printStackTrace();
            }

            System.err.println("< " + getThreadName() + " create()");
      }

      public void run () {
            System.err.println("? " + getThreadName() + " run()");
            leaf();
      }

      public void leaf () {
            System.err.println("? " + getThreadName() + " leaf()");
      }

      public static String getThreadName () {
            return "[" + Thread.currentThread().getName() + "]";
      }
}

public aspect Aspect percflow(root() || run()) {

      private Object state;
      private static Map states = new HashMap(); /* Thread -> State */

      private Aspect () {
            System.err.println("? " + Main.getThreadName() + " Aspect.<init>()");
      }

      pointcut root () :
            execution(public void root(..));

      pointcut create () :
            call(Thread.new(..)) && withincode(public void create(..));

      pointcut run () :
            execution(public void run(..));

      pointcut leaf () :
            execution(public void leaf(..));

      before (Object obj) : root() && this(obj) {
            state = obj;
      }

      after () returning(Thread thread) : create () {
            putState(thread,state);
      }

      before () : run () {
            state = getState(Thread.currentThread());
      }

      before () : leaf () {
            System.err.println("? " + Main.getThreadName() + " " + thisJoinPoint.getSignature() + " state=" + state);
      }

      private static void putState (Object obj, Object state) {
            states.put(obj,state);
      }

      private static Object getState (Object obj) {
            return states.get(obj);
      }
}

Matthew Webster
AOSD Project
Java Technology Centre, MP146
IBM Hursley Park, Winchester,  SO21 2JN, England
Telephone: +44 196 2816139 (external) 246139 (internal)
Email: Matthew Webster/UK/IBM @ IBMGB, matthew_webster@xxxxxxxxxx
http://w3.hursley.ibm.com/~websterm/



Back to the top