Не совсем уверен, к чему вы стремитесь, но несколько замечаний:
Во-первых, вам не нужно делать lock1 и lock2, чтобы различать Unit и другой тип.Единица - это правильный тип значения, для него тоже будет работать универсальный метод.Кроме того, вам, вероятно, следует использовать вызов по имени аргумента => T, а не функцию () => T, и использовать два списка аргументов:
def lock[T] (uniqueID:Any)(f: => T) : T = {
acquireLock (uniqueID)
try {
f
} finally {
releaseLock (uniqueID)
}
}
Затем вы можете вызвать с помощью lock(id){block}
ивыглядит как общие инструкции, например, если или синхронизированы.
Во-вторых, зачем вам уникальный идентификатор, зачем делать Lock одиночным?Вместо этого сделайте Lock
классом, у которого будет столько экземпляров, сколько у вас было бы идентификаторов.
class Lock {
def lock[T](f: => T): T = {acquireLock() ...}
}
(Вы можете даже назвать свой метод блокировки apply
, так что вы можете просто сделать myLock{....}
вместо myLock.lock{...}
)
Многопоточность в стороне, теперь вам просто нужен логический var для acquire
/ releaseLock
Наконец, если вам нужно поддерживать многопоточность, вы должны решить, следует линесколько потоков могут войти в замок (это не было бы рекурсией).Если они могут, логическое значение должно быть заменено на DynamicVariable[Boolean]
(или, возможно, java ThreadLocal
, поскольку DynamicVariable
- это InheritableThreadLocal
, что вы можете или не можете хотеть).Если они не могут, вам просто нужно синхронизировать доступ в acquire
/ releaseLock
.