在Java中根据监视器对象的特定属性同步线程
我的程序模拟在存储库上工作。 必须同步的资源是在Java中根据监视器对象的特定属性同步线程,java,multithreading,Java,Multithreading,我的程序模拟在存储库上工作。 必须同步的资源是存储库对象(用作监视器)中的数组单元格。 允许线程(RepoThreadclass)向数组的单元格值添加值或从中减去值,但仅当没有其他线程在同一单元格上执行相同操作时RepoThreads在不同的单元格上同时执行操作(加法/减法)。 当前正在处理的单元格将被视为“繁忙”,其索引将存储在HashMap中 我有这些课程(: 我的问题是,似乎没有发生冲突,因为我的add和remove方法是synchronized。这意味着当任何线程执行添加或移除操作时,
存储库
对象(用作监视器)中的数组单元格
。
允许线程(RepoThread
class)向数组的单元格值添加值或从中减去值,但仅当没有其他线程在同一单元格上执行相同操作时RepoThread
s在不同的单元格上同时执行操作(加法/减法)。
当前正在处理的单元格将被视为“繁忙”,其索引将存储在HashMap中
我有这些课程(:
我的问题是,似乎没有发生冲突,因为我的
add
和remove
方法是synchronized
。这意味着当任何线程执行添加或移除操作时,存储库
对象被锁定,并且没有其他线程可以访问数组,因为整个对象被锁定,而不仅仅是忙碌的线程牢房
我应该做什么更改,这样线程就可以在存储库对象上做任何他们想做的事情,只要他们在一个非繁忙的
单元格数组中做这些事情?如果我理解你的问题,你想直接更精确地锁定单元格,对吗?如果是的话
一个选项是用单元格对象本身上的同步块替换同步(如果您创建了单元格对象的数组,这意味着您创建了一个单元格类)
另一种选择是通过一个ReentrantLock数组进行锁定,每个单元格一个
ReentrantLock [] locks = new ReentrantLock[nb];
// fill the array of ReentranLock, one per cell
locks[cellRank].lock();
try {
// your stuff
} finally {
lock[cellRank].unlock();
}
感谢您的回复。是否仍要使用同步块和无锁等待?如果使用同步块(第一种可能性),您仍然可以使用cells[i]等待cells[i]。wait()
并使用cells[i]唤醒它们。notifyAll()
。这不是你想要的吗?单元格是原始类型。你的第二个建议对我有效。谢谢!
public class RepoThread extends Thread {
Repository mon;
int id;
int addOrRemove;
int index;
int amount;
public RepoThread(Repository mon, int id, int addOrRemove, int index, int amount) {
this.mon = mon;
this.id = id;
this.addOrRemove = addOrRemove;
this.index = index;
this.amount = amount;
}
public void run() {
if (addOrRemove == 1) {
mon.add(index, amount,id);
}else if(addOrRemove==2){
mon.remove(index, amount, id);
}else{
System.out.println("unknown operation requested");
}
}
}
public class TestRepository {
public static void main(String[] args) {
Repository repo = new Repository(10, 5);
RepoThread remover1 = new RepoThread(repo, 1, 2, 5, 8);
remover1.start();
RepoThread remover2 = new RepoThread(repo, 2, 2, 5, 4);
remover2.start();
RepoThread adder1 = new RepoThread(repo, 3, 1, 5, 4);
adder1.start();
RepoThread adder2 = new RepoThread(repo, 4, 1, 5, 2);
adder2.start();
RepoThread adder3 = new RepoThread(repo, 5, 1, 7, 4);
adder3.start();
RepoThread adder4 = new RepoThread(repo, 6, 1, 5, 4);
adder4.start();
}
}
// Example
Cell [] cells = new Cell[nb];
// initialize the array as you need
// later on, in remove or add
synchronize (cells[i]) {
// your stuff
}
ReentrantLock [] locks = new ReentrantLock[nb];
// fill the array of ReentranLock, one per cell
locks[cellRank].lock();
try {
// your stuff
} finally {
lock[cellRank].unlock();
}