制作静态ReentrantLocks

时间:2017-12-08 21:12:08

标签: java multithreading reentrantlock

前段时间我偶然发现了这个帖子: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' 作为最后一件事。这样他们就有了一个共享锁来保护处理同步。

感谢。

2 个答案:

答案 0 :(得分:2)

在类级别使用静态Lock进行同步是绝对正常的。您也可以使用

synchronized (FileProcessor.class) {
    //your code
}

答案 1 :(得分:0)

有一段时间,使用全局变量是最好的选择。使用Concurrency API,您可以使用更简单的方法,例如:

  1. 您可以创建一个Runnable来执行FileProcessor中的代码并将其提交给Executor。您将执行程序配置为单线程,并且您已完成。

  2. 如果您有几个地方可以开始工作,并且您希望确保只有一个地方可以运行。想象一下,你想在程序启动时然后在16:00运行它。现在有人在15:59启动程序 - 工作可能会启动两次。为避免这种情况,请使用AtomicBoolean

    保护代码
    private AtomicBoolean guard = new AtomicBoolean(true);
    
    if (guard.getAndSet(false)) {
        try {
            ... do job ...
        } finally {
            guard.set(true);
        }            
    }