[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Re:

FYI: using my aspect as is, and it does look proper, I get
IllegalMonitorStateException inside my tests. Pulling out the aspect
and putting the same code in place manually does not. To me, this
means that something is going on inside AspectJ-generated code that is
not correct.

I also found that AspectJ puts an instance variable and interface on
EVERY class, regardless of whether the class actually contains a
@ReadLock or @WriteLock annotated method. It should be able to
statically identify the classes that can possibly be affected, and
only weave those classes.

On 4/24/06, Howard Lewis Ship <hlship@xxxxxxxxx> wrote:
> I'm writing some synchronization aspects now.
>
> I want to annotation methods with @ReadLock or @WriteLock and have the
> annotation manage the lock.
>
> So far, so good:
>
> package org.apache.tapestry.internal.aspects;
>
> import java.util.concurrent.locks.ReadWriteLock;
> import java.util.concurrent.locks.ReentrantReadWriteLock;
>
> import org.apache.tapestry.internal.annotations.ReadLock;
> import org.apache.tapestry.internal.annotations.WriteLock;
>
> /**
>  * Associates a {@link java.util.concurrent.locks.ReadWriteLock} with
> an object instance; the
>  * {@link ReadLock} and {@link WriteLock} annotations drive this.
> Methods that have the ReadLock
>  * annotation witll be advised to obtain and release the read lock
> around their execution. Methods
>  * with the WriteLock annotation will obtain and release the write
> lock around their execution.
>  * Methods with ReadLock that call a WriteLock-ed method (within the
> same instance) will release the
>  * read lock before invoking the WriteLock-ed method.
>  * <p>
>  * This aspect also enforces that the annotations are only applied to
> instance (not static) methods.
>  *
>  * @author Howard M. Lewis Ship
>  */
> public abstract aspect Synchronization extends AbstractClassTargetting
> perthis(readLockMethods() || writeLockMethods())
> {
>     private final ReadWriteLock _lock = new ReentrantReadWriteLock();
>
>     declare error :
>         targetClasses() &&
>         execution(@(ReadLock || WriteLock) static * *(..)) :
>             "ReadLock and WriteLock annotations may only be applied to
> instance methods.";
>
>     declare error :
>         targetClasses() &&
>         execution(@ReadLock @WriteLock * *(..)) :
>             "A method may be annotated with ReadLock or with WriteLock
> but not both.";
>
>     pointcut readLockMethods() :
>         targetClasses() &&
>         execution(@ReadLock * *(..));
>
>     pointcut writeLockMethods() :
>         targetClasses() &&
>         execution(@WriteLock * *(..));
>
>     /** Before read lock methods, acquire the read lock. */
>     before() : readLockMethods()
>     {
>         _lock.readLock().lock();
>     }
>
>     /** After read lock methods (including thrown exceptions), release
> the read lock. */
>     after() : readLockMethods()
>     {
>         _lock.readLock().unlock();
>     }
>
>     /**
>      * Before write lock methods, acquire the write lock. Note that
> obtaining the write lock will
>      * block indefinately if the current thread has a read lock, but
> we handle that as a special
>      * case.
>      */
>
>     before(): writeLockMethods()
>     {
>         _lock.writeLock().lock();
>     }
>
>     /** And release the write lock after the method completes
> (successfully, or with an exception). */
>     after() : writeLockMethods()
>     {
>         _lock.writeLock().unlock();
>     }
>
> }
>
>
> Here's my new issues:
>
> 1. Using perthis() creates the aspect instance dynamically, but I'm
> worried that it uses a synchronized block that will serialize my
> methods after all the effort I've put in to make them highly parallel
> (using the readwrite lock).
>
> 2. One very important case is not coverred:
>
> If a method with @ReadLock invokes a method OF THE SAME INSTANCE with
> @WriteLock, then we need to release the read lock before we invoke the
> write lock method, then re-obtain the read lock afterwards.  This
> feels like something you would do with cflow(), but I can't figure out
> how to bind to an instance, rather than a type.
>
> BTW, I'm finding the combintation of Aspects and Annotations to be
> very powerful.
> Using annotations to mark types or methods works well in combintaion
> with a base aspect that defines an abstract targetClasses() pointcut.
> Concrete aspects provide a specific set of classes for targetClasses()
> and the annotation matching does the rest.
>
> Thanks in advance!
> --
> Howard M. Lewis Ship
> Independent J2EE / Open-Source Java Consultant
> Creator, Jakarta Tapestry
> Creator, Jakarta HiveMind
>
> Professional Tapestry training, mentoring, support
> and project work.  http://howardlewisship.com
>


--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind

Professional Tapestry training, mentoring, support
and project work.  http://howardlewisship.com