gpt4 book ai didi

java - 通过java锁定数组中的每个项目

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:34:00 25 4
gpt4 key购买 nike

假设我们有这些类:

public  class Record {
int key;
int value;
Record(){
this.key=0;
this.value=0;
}
Record(int key,int value){
this.key=key;
this.value=value;
}
public class Table {
static final Record[] table = new Record [100];
static final Object[] locks = new Object[table.length];
static{
for(int i = 0; i < table.length; i++) {
locks[i] = new Object();
}


table[0]=new Record(0,0);
table[1]=new Record(1,10);
table[2]=new Record(2,20);
table[3]=new Record(3,30);
}
}

我想在 TRAnsaction 类中实现这些方法

void setValueByID(int key, int value)

在 setValueByID 方法完成之前,键值对(记录)被锁定(不能从其他事务读取/写入)。

int getValueByID(int key)

键值对(记录)被锁定,直到事务提交

void commit()

它会解锁当前交易中锁定的所有键值对(记录)

所以,我的实现是:

class Transaction extends Thread {
//there is no problem here
public void setValueByID(int key, int value){

synchronized(Table.locks[key]) {
Table.table[key].key=key;

}
}
//the problem is here...
//how can i make other thread wait until current thread calls Commit()
public int getValueByID(int key){
int value=0;
synchronized(Table.locks[key]){
value= Table.table[key].key;
}
return value;
}


void commit(){
}

艾哈迈德

最佳答案

你不能使用同步块(synchronized block)来实现它,相反你需要使用类似锁的东西。

public Main {
public static void main(String[] args) {
final Transaction T = new Transaction();
for (int n = 0; n < 10; n++) {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
T.setValueByID(i % 100, i);
T.getValueByID(i % 100);
if (i % 20 == 0) T.commit();
}
}
}).start();
}
}
}
class Table {
static final Record[] table = new Record[100];
static final ReentrantLock[] locks = new ReentrantLock[table.length];

static {
for (int i = 0; i < table.length; i++) {
locks[i] = new ReentrantLock();
}

table[0] = new Record(0, 0);
table[1] = new Record(1, 10);
table[2] = new Record(2, 20);
table[3] = new Record(3, 30);
}
}
class Transaction {

private ThreadLocal<Set<ReentrantLock>> locks = new ThreadLocal<Set<ReentrantLock>>() {
@Override
protected Set<ReentrantLock> initialValue() {
return new HashSet<ReentrantLock>();
}
};

private void attainLock(int key) {
final ReentrantLock lock = Table.locks[key];
lock.lock();
locks.get().add(lock);
}

private void releaseLock(int key) {
final ReentrantLock lock = Table.locks[key];
releaseLock(lock);
}

private void releaseLock(ReentrantLock lock) {
final Set<ReentrantLock> lockSet = locks.get();
if (!lockSet.contains(lock)) {
throw new IllegalStateException("");
}
lockSet.remove(lock);
lock.unlock();
}

private void releaseLocks() {
final Set<ReentrantLock> lockSet = new HashSet<ReentrantLock>(locks.get());
for (ReentrantLock reentrantLock : lockSet) {
releaseLock(reentrantLock);
}
}

public void setValueByID(int key, int value) {
attainLock(key);
Table.table[key].key = key;
releaseLock(key);
}

public int getValueByID(int key) {
attainLock(key);
return Table.table[key].key;
}

void commit() {
releaseLocks();
}
}

锁的问题在于,在您的交易过程中,如果您在获得锁时不遵循命令,您可能会陷入死锁!此外,您需要确保正确处理异常并始终通过调用 commit() 释放锁。

关于java - 通过java锁定数组中的每个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10360472/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com