Есть ли аннотация, связанная с блокировкой python, которая имеет такой же эффект для метода python, что и "синхронизированное" ключевое слово для java-методов?
Аннотация метода блокировки питона
Ответ 1
Я могу предположить, что в python не существует встроенной функции, но вы можете реализовать ее, понимая, как она работает на Java из этой ссылки:
Каждый объект Java, созданный, включая каждый загруженный класс имеет связанный блокировки или монитора. Ввод кода внутри синхронизированный блок делает компилятор добавить инструкции для получения блокировка указанного объекта до выполнение кода и его выпуск впоследствии (либо потому, что код нормально или ненормально). Между приобретением замка и выпуская его, говорят, что нить "собственный" замок. В точке Thread Желание приобрести замок, если Thread B уже владеет этим, тогда Поток A должен ждать Thread B отпустите его.
возможно, что-то вроде этого может работать:
синхронизированный оператор в java:
public class Java {
static private int count = 0;
public void increment() {
synchronized (this) {
count++;
}
}
}
стал:
import threading
class Java:
cout = 0
lock = threading.RLock()
def increment():
with Java.lock:
Java.cout += 1
и синхронизированный метод в Java:
public class Java {
static private int count = 0;
public synchronized void increment() {
count ++;
}
}
стали:
import threading
def synchronized(method):
""" Work with instance method only !!! """
def new_method(self, *arg, **kws):
with self.lock:
return method(self, *arg, **kws)
return new_method
class Java:
count = 0
lock = threading.RLock()
@synchronized
def incremenet(self):
Java.count += 1
Явный лучше, чем неявный.
NB: мои знания на Java очень ограничены, и это моя первая лекция об этой Java-функции, поэтому, возможно, я что-то пропустил (или, может быть, я пропустил все здесь):), надеюсь, этот ответ может помочь кому-то.
NB: блокировка, которую я создал, представляет собой переменную класса, поэтому синхронизация потоков выполняется на уровне класса, если мы хотим сделать синхронизацию на уровне экземпляра (только), которая, как мне кажется, соответствует тому, как это делает Java, приведенный выше код должен измениться.
Ответ 2
Я иногда использую такой декоратор:
def synchronized(f):
@functools.wraps(f)
def wrapper(self, *args, **kwargs):
try:
_ = self._lock
except AttributeError:
self._lock = threading.Lock()
with self._lock:
return f(self, *args, **kwargs)
return wrapper
Это решение имеет условие гонки при вызове метода украшений в первый раз. Самый простой способ избежать этой проблемы - вызвать один синхронизированный метод, когда ни один другой поток не запускается первым, или назначить self._lock
вручную в __init__