说我有以下代码:
@SpringBootApplication
public class RedglassCoreApplication {
public static void main(String[] args) {
SpringApplication.run(RedglassCoreApplication.class, args);
}
@Bean
public DataSource dataSource() {
return //DataSource Instance
}
}
(让我们抛开上面代码的无用之处。这里的唯一目的是帮助解释问题。)
在import threading
class Check(threading.Thread):
def __init__(self, item):
super(Check, self).__init__()
self._item = item
def run(self):
data = '{} ({} total)'.format(self._item, total)
collected.append(data)
items = ['item{}'.format(i) for i in xrange(5)]
total = len(items)
collected = []
for item in items: Check(item).start()
类的total
方法内部是否有更多的Python方式访问collected
和run
?保证Check
的值不变。据我所知,我无法将其他任何内容传递给total
方法。将相同的run
和total
值传递给collected
类的构造函数似乎很愚蠢,但这也许是最佳实践吗?
答案 0 :(得分:3)
global
和线程组合不是很好的组合。至少,如果要更改共享状态,则应该有适当的锁,global
是可以拥有的“共享”状态的最极端情况。
我绝对建议您将item
和total
都传递到您的Check
类中,然后从线程中检索值,然后稍后“组合”它:
import threading
class Check(threading.Thread):
def __init__(self, item, total):
super(Check, self).__init__()
self._item = item
self._total = total
self.result = None
def run(self):
data = '{} ({} total)'.format(self._item, self._total)
self.result = data
items = ['item{}'.format(i) for i in xrange(5)]
total = len(items)
collected = []
checks = [Check(item) for item in items]
for check in checks:
check.start()
for check in checks:
check.join()
collected = [check.result for check in checks]
但是如果您可以使用Python 3,则更好的方法是避免子类Thread
并首先直接处理它们:
from concurrent.futures import ThreadPoolExecutor
def do_check(item, total):
data = '{} ({} total)'.format(self._item, self._total)
return data
items = ['item{}'.format(i) for i in range(5)]
total = len(items)
tpe = ThreadPoolExecutor(max_workers=5)
collected = list(tpe.map(lambda item: do_check(item, total), items))
没有global
,没有线程和更少的代码行。
答案 1 :(得分:0)
如果您完全确定自己将始终在函数中使用相同的全局变量,并且全局变量永远不会改变,那么就无需使用参数。
最Python的方法是使用total
关键字明确指定collected
和global
是全局变量:
def run(self):
global total
global collected
data = '{} ({} total)'.format(self._item, total)
collected.append(data)
答案 2 :(得分:0)
我在代码中添加了一个锁,这是一种实现方法。
collected
,total
是类变量,并且由于它是共享状态,因此最好用锁来保护它。请注意,将实例变量设为lock
会达到目的,因此它是一个类变量。
import threading
class Check(threading.Thread):
collected = []
total = 0
lock = threading.Lock()
def __init__(self, item):
super(Check, self).__init__()
self._item = item
def run(self):
data = '{} ({} total)'.format(self._item, self.total)
with self.lock:
self.collected.append(data)
items = ['item{}'.format(i) for i in range(5)]
Check.total = len(items)
for item in items:
Check(item).start()
print (Check.total)
print (Check.collected)