- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力使用 AspectJ 为每个构造的、属于 Mystruct 类型的对象创建一个 ReentrantReadWriteLock。这是我的源代码。
方面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Aspect
public class LocksAspect {
private ReentrantReadWriteLock rwLock;
private Lock acquireReadLock;
private Lock acquireWriteLock;
@Before("!within(LocksAspect)&&execution(*.new(..))")
public void LookupBefores() {
rwLock = new ReentrantReadWriteLock();
acquireReadLock = rwLock.readLock();
acquireWriteLock = rwLock.writeLock();
}
@Pointcut("call(void MyStructure.Insert(String))")
public void InsertPointcut() {
}
@Pointcut("call(void MyStructure.Read(int))")
public void ReadPointcut() {
}
@Before("InsertPointcut()")
public void InsertPointcutBefore(JoinPoint pointcut) throws InterruptedException {
acquireWriteLock.lock();
String thrdName = Thread.currentThread().getName();
System.out.println(thrdName + " is entering in critical Section {} ");
Thread.sleep(10000);
}
@After("InsertPointcut()")
public void InsertPointcutAfter(JoinPoint pointcut) {
String thrdName = Thread.currentThread().getName();
System.out.println(thrdName + " received notification and is exiting critical Section {} ");
acquireWriteLock.unlock();
}
@Before("ReadPointcut()")
public void ReadPointcutBefore(JoinPoint pointcut) throws InterruptedException {
acquireReadLock.lock();
String thrdName = Thread.currentThread().getName();
System.out.println(thrdName + " is entering in critical Section {} ");
Thread.sleep(1000);
}
@After("ReadPointcut()")
public void ReadPointcutAfter(JoinPoint pointcut) {
String thrdName = Thread.currentThread().getName();
System.out.println(thrdName + " received notification and is exiting critical Section {} ");
acquireReadLock.unlock();
}
}
Thread writer 类。(Reader 线程类并不重要,因为我的问题不同,所以我省略了它)
public class Writer extends Thread{
private MyStructure myStructure;
public Writer(MyStructure myStructure) {
this.myStructure=myStructure;
}
@Override
public void run() {
this.myStructure.Insert("example");
}
}
我的结构类
import java.util.ArrayList;
public class MyStructure {
ArrayList<String> examplelist;
public MyStructure() {
examplelist = new ArrayList<String>();
}
public void Insert(String value) {
examplelist.add(value);
}
public void Read(int pos) {
examplelist.get(pos);
}
}
主要内容
MyStructure structure = new MyStructure();
MyStructure structure1 = new MyStructure();
new Thread(new Writer(structure), "Thread1").start();
new Thread(new Writer(structure1), "Thread2").start();
输出
Thread2 is entering in critical Section {}
Thread2 received notification and is exiting critical Section {}
Thread1 is entering in critical Section {} //Thread1 will wait for Thread2 to release the lock in critical section which is wrong
Thread1 received notification and is exiting critical Section {}
现在我的问题是如何为创建的 Mystruct 的每个对象获取新的 ReentrantReadWriteLock 。例如,如果我们运行上面的示例,Thread1 和 Thread2 都必须能够访问临界区,因为它们具有不同的对象引用,但这不应该发生。我的问题是 Thread2 将阻塞并等待 Thread1 完成,这是错误的。如何绕过 Aspect4j 的构建问题?
最佳答案
解决问题的关键是每个MyStructure
需要一组锁。实例。不过,您的方面是单例。因此,您要么需要使用另一个方面实例化方案(这就是我将在我的答案中使用的方案),要么通过保留一组锁来在单例方面进行手动簿记,并在 MyStructure
时向该集中添加一个新元素。对象已创建。
为了更好地理解我的回答,请引用AspectJ手册了解aspect instantiation的信息.
在我们开始之前,先说一些关于您的代码的评论以及为什么我对其进行了一些更改:
Writer
已经是 Thread
子类,无需将其包装到另一个线程实例中。 (我知道您这样做可能只是为了能够命名线程,但这可以通过在类中添加一个构造函数来实现,该构造函数接受名称参数并将其传递给父类(super class)构造函数。)JoinPoint
类型的变量pointcut
因为连接点不是 AOP 方面的切入点。Object
如果您想针对非 void 方法,则实际上会返回一些内容。在这里这是没有必要的,因为在这两种情况下我们都有 void 方法。Reader
类并使用它来显示可重入读锁与写锁之间的区别。MyStructure
可命名和可打印的实例,以便在日志中更轻松地识别目标对象。MyStructure
读取时出现异常污染日志。在写入之前,我确保 MyStructure
在构造函数中获取默认元素。为了保持示例代码简单,我不想在这里捕获异常。现在有什么解决办法吗?基本上就是这样,因为上面提到的更改只是使代码更好或测试程序更接近现实生活情况:
@Aspect("pertarget(execution(de.scrum_master.app.MyStructure.new(..)))")
public class LocksAspect { // (...)
这会为每个MyStructure
创建一个方面实例。目的。这也是为什么我们可以分配 readWriteLock
的值。 , readLock
和writeLock
直接而不是像在单例方面那样使用特殊的切入点+建议对。
这是完整的、重构的示例代码:
应用程序代码+驱动程序应用程序:
package de.scrum_master.app;
import java.util.ArrayList;
import java.util.List;
public class MyStructure {
private String name;
private List<String> myList;
public MyStructure(String name) {
this.name = name;
myList = new ArrayList<String>();
myList.add("dummy element to permit reading");
}
public void insert(String value) {
myList.add(value);
}
public void read(int pos) {
myList.get(pos);
}
@Override
public String toString() {
return "MyStructure[" + name + "]";
}
}
package de.scrum_master.app;
public class Writer extends Thread {
private MyStructure myStructure;
public Writer(MyStructure myStructure) {
this.myStructure = myStructure;
}
@Override
public void run() {
myStructure.insert("example");
}
}
package de.scrum_master.app;
public class Reader extends Thread {
private MyStructure myStructure;
public Reader(MyStructure myStructure) {
this.myStructure = myStructure;
}
@Override
public void run() {
myStructure.read(0);
}
}
package de.scrum_master.app;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Application {
public static void main(String[] args) {
MyStructure structureA = new MyStructure("One");
MyStructure structureB = new MyStructure("Two");
List<Thread> threads = Arrays.asList(
new Writer(structureA), new Writer(structureB), new Writer(structureA), new Writer(structureB),
new Reader(structureA), new Reader(structureB), new Reader(structureA), new Reader(structureB),
new Reader(structureA), new Reader(structureB), new Reader(structureA), new Reader(structureB)
);
Collections.shuffle(threads);
for (Thread thread : threads)
thread.start();
}
}
方面:
package de.scrum_master.aspect;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import de.scrum_master.app.MyStructure;
@Aspect("pertarget(execution(de.scrum_master.app.MyStructure.new(..)))")
public class LocksAspect {
private static final long startTime = System.currentTimeMillis();
private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private Lock readLock = readWriteLock.readLock();
private Lock writeLock = readWriteLock.writeLock();
@Around("target(myStructure) && execution(void insert(String))")
public void InsertPointcutBefore(ProceedingJoinPoint thisJoinPoint, MyStructure myStructure) throws Throwable {
writeLock.lock();
log("entering write section", myStructure);
try {
Thread.sleep(1000);
thisJoinPoint.proceed();
} finally {
log("exiting write section", myStructure);
writeLock.unlock();
}
}
@Around("target(myStructure) && execution(void read(int))")
public void ReadPointcutBefore(ProceedingJoinPoint thisJoinPoint, MyStructure myStructure) throws Throwable {
readLock.lock();
log("entering read section", myStructure);
try {
Thread.sleep(1000);
thisJoinPoint.proceed();
} finally {
log("exiting read section", myStructure);
readLock.unlock();
}
}
private static void log(String message, Object targetObject) {
System.out.printf(
"%8d ms | %-25s | %-17s | %s%n",
System.currentTimeMillis() - startTime,
Thread.currentThread(),
targetObject,
message
);
}
}
日志输出示例:
4 ms | Thread[Thread-3,5,main] | MyStructure[Two] | entering write section
4 ms | Thread[Thread-6,5,main] | MyStructure[One] | entering read section
4 ms | Thread[Thread-8,5,main] | MyStructure[One] | entering read section
4 ms | Thread[Thread-4,5,main] | MyStructure[One] | entering read section
4 ms | Thread[Thread-10,5,main] | MyStructure[One] | entering read section
1019 ms | Thread[Thread-3,5,main] | MyStructure[Two] | exiting write section
1020 ms | Thread[Thread-8,5,main] | MyStructure[One] | exiting read section
1020 ms | Thread[Thread-4,5,main] | MyStructure[One] | exiting read section
1020 ms | Thread[Thread-11,5,main] | MyStructure[Two] | entering read section
1020 ms | Thread[Thread-5,5,main] | MyStructure[Two] | entering read section
1020 ms | Thread[Thread-6,5,main] | MyStructure[One] | exiting read section
1020 ms | Thread[Thread-10,5,main] | MyStructure[One] | exiting read section
1025 ms | Thread[Thread-2,5,main] | MyStructure[One] | entering write section
2023 ms | Thread[Thread-11,5,main] | MyStructure[Two] | exiting read section
2024 ms | Thread[Thread-5,5,main] | MyStructure[Two] | exiting read section
2025 ms | Thread[Thread-1,5,main] | MyStructure[Two] | entering write section
2026 ms | Thread[Thread-2,5,main] | MyStructure[One] | exiting write section
2026 ms | Thread[Thread-0,5,main] | MyStructure[One] | entering write section
3026 ms | Thread[Thread-1,5,main] | MyStructure[Two] | exiting write section
3026 ms | Thread[Thread-7,5,main] | MyStructure[Two] | entering read section
3026 ms | Thread[Thread-9,5,main] | MyStructure[Two] | entering read section
3028 ms | Thread[Thread-0,5,main] | MyStructure[One] | exiting write section
4028 ms | Thread[Thread-7,5,main] | MyStructure[Two] | exiting read section
4029 ms | Thread[Thread-9,5,main] | MyStructure[Two] | exiting read section
关于java - 对于 MyStructure 的每个初始化类型,具有 AspectJ 切入点的 ReentrantReadWriteLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53270967/
我是 Spring 新手,这就是我想要做的事情: 我正在使用一个基于 Maven 的库,它有自己的 Spring 上下文和 Autowiring 字段。 它的bean配置文件是src/test/res
我在我的测试脚本中有以下列表初始化: newSequenceCore=["ls", "ns", "*", "cm", "*", "ov", "ov", "ov", "ov", "kd"] (代表要在控
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Class construction with initial values 当我查看 http://en.
我得到了成员变量“objectCount”的限定错误。编译器还返回“ISO C++ 禁止非常量静态成员的类内初始化”。这是主类: #include #include "Tree.h" using n
我有如下所示的a.h class A { public: void doSomething()=0; }; 然后我有如下所示的b.h #include "a.h" class b: publi
我需要解析 Firebase DataSnapshot (一个 JSON 对象)转换成一个数据类,其属性包括 enum 和 list。所以我更喜欢通过传递 DataSnapshot 来手动解析它进入二
我使用 JQuery 一段时间了,我总是使用以下代码来初始化我的 javascript: $(document).ready( function() { // Initalisation logic
这里是 Objective-C 菜鸟。 为什么会这样: NSString *myString = [NSString alloc]; [myString initWithFormat:@"%f", s
我无法让核心数据支持的 NSArrayController 在我的代码中正常工作。下面是我的代码: pageArrayController = [[NSArrayController alloc] i
我对这一切都很陌生,并且无法将其安装到我的后端代码中。它去哪里?在我的页脚下面有我所有的 JS? 比如,这是什么意思: Popup initialization code should be exec
这可能是一个简单的问题,但是嘿,我是初学者。 所以我创建了一个程序来计算一些东西,它目前正在控制台中运行。我决定向其中添加一个用户界面,因此我使用 NetBeans IDE 中的内置功能创建了一个 J
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
据我所知, dependentObservable 在声明时会进行计算。但如果某些值尚不存在怎么办? 例如: var viewModel ={}; var dependentObservable1 =
我正在阅读 POODR 这本书,它使用旧语法进行默认值初始化。我想用新语法实现相同的功能。 class Gear attr_reader :chainring, :cog, :wheel de
我按照 polymer 教程的说明进行操作: https://www.polymer-project.org/3.0/start/install-3-0 (我跳过了可选部分) 但是,在我执行命令“po
很抱歉问到一个非常新手的Kotlin问题,但是我正在努力理解与构造函数和初始化有关的一些东西。 我有这个类和构造函数: class TestCaseBuilder constructor(
假设我们有一个包含 30 列和 30 行的网格。 生命游戏规则简而言之: 一个小区有八个相邻小区 当一个细胞拥有三个存活的相邻细胞时,该细胞就会存活 如果一个细胞恰好有两个或三个活的相邻细胞,那么它就
我是 MQTT 和 Android 开放附件“AOA” 的新手。在阅读教程时,我意识到,在尝试写入 ByteArrayOutputStream 类型的变量之前,应该写入 0 或 0x00首先到该变量。
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
我有一个inotify /内核问题。我正在使用“inotify” Python项目进行观察,但是,我的问题仍然是固有的关于inotify内核实现的核心。 Python inotify项目处理递归ino
我是一名优秀的程序员,十分优秀!