前段时间我偶然发现了这个帖子:Does making a reentrant lock static and make it a mutex?我自己还有一个问题:
如果创建private static final ReentrantLock lock
不被视为代码异味,我感兴趣吗?我已经读过静态变量是邪恶的,但我当前的用例我正在研究看起来像是使用它的理想场所。
有人愿意帮忙吗?
使用详细信息进行编辑:我有这个类,称之为FileProcessor
,它在另一个线程中执行给定的作业。我的用例是激活这个类的一些实例并完成这些工作。但我想做的是确保只有其中一人能够立刻完成这项工作,他们会轮流执行这项工作。
所以我想我会给static ReentrantLock
lock()
run()
作为unlock()
块中的第一件事,DECLARE @BIT AS BIT = 0
IF OBJECT_ID('tempdb..#TALLY') IS NOT NULL
DROP TABLE #TALLY
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO #TALLY
FROM sys.objects s1 --use sys.columns if you don't get enough rows returned to generate all the numbers you need
CROSS JOIN sys.objects s2 --use sys.co
ALTER TABLE #TALLY ADD PRIMARY KEY(Number)
PRINT CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))+' milliseconds'
作为最后一件事。这样他们就有了一个共享锁来保护处理同步。
感谢。
答案 0 :(得分:2)
在类级别使用静态Lock
进行同步是绝对正常的。您也可以使用
synchronized (FileProcessor.class) {
//your code
}
答案 1 :(得分:0)
有一段时间,使用全局变量是最好的选择。使用Concurrency API,您可以使用更简单的方法,例如:
您可以创建一个Runnable
来执行FileProcessor
中的代码并将其提交给Executor
。您将执行程序配置为单线程,并且您已完成。
如果您有几个地方可以开始工作,并且您希望确保只有一个地方可以运行。想象一下,你想在程序启动时然后在16:00运行它。现在有人在15:59启动程序 - 工作可能会启动两次。为避免这种情况,请使用AtomicBoolean
:
private AtomicBoolean guard = new AtomicBoolean(true);
if (guard.getAndSet(false)) {
try {
... do job ...
} finally {
guard.set(true);
}
}