Python 锁定方法注解

14 投票
2 回答
9460 浏览
提问于 2025-04-16 09:34

有没有一种Python的锁注解,能像Java中的“synchronized”关键字一样,对Python的方法起到相同的作用?

2 个回答

1

我有时候会用这样的装饰器:

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

不过,这个解决方案在第一次调用被装饰的方法时会出现竞争条件。为了避免这个问题,最简单的方法是在没有其他线程运行时,先调用一个同步的方法,或者在__init__里手动给self._lock赋值。

17

我可以假设在Python中没有内置的功能,但你可以通过理解Java中的工作原理来实现它,具体可以参考这个链接

每个创建的Java对象,包括每个加载的类,都有一个相关的锁或监视器。把代码放在一个同步块里,编译器会在执行代码之前添加指令来获取指定对象的锁,并在执行完后释放锁(无论代码是正常结束还是异常结束)。在获取锁和释放锁之间,线程被认为是“拥有”这个锁的。如果线程A想要获取锁,而线程B已经拥有了这个锁,那么线程A就必须等线程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

明确的比隐含的要好。

注意:我对Java的了解非常有限,这也是我第一次学习这个Java特性,所以可能我遗漏了一些东西(或者可能我完全没抓住重点 :)),希望这个回答能帮助到某个人。

注意:我创建的锁是一个类变量,所以线程同步发生在类级别。如果我们想在实例级别(仅)进行同步,我认为这就是Java的做法,那么上面的代码就必须进行更改。

撰写回答