【问题标题】:How to set timeout to Lock mechanism?如何将超时设置为锁定机制?
【发布时间】:2018-03-19 10:15:08
【问题描述】:

我有一个名为 X 的全局变量(对象)。另外我有两个不同的线程,分别名为 ThreadA 和 ThreadB,它们同时使用 X。

ThreadA 加 1 100 次,ThreadB 乘 2 2 次。

当我同时启动它们时,并发发生并且我看到了一些东西

1
2
3
6
7
14.. etc

我已经通过添加解决了这个问题

ReentrantLock  lock = new ReentrantLock();
lock.lock();
..
lock.unlock();

机制。

现在我的代码可以工作了

1
2
3
4
...
100
200
400

但我想添加超时,所以如果 ThreadA 花费超过 2 秒,想要释放锁,以便 ThreadB 可以操作它。

想看类似的东西

1
(wait 100ms)
2
(wait 100ms)
3
...
20
400
800
801
( wait 100ms)
802
...

我已经尝试过 trylock(2000,TimeUnit.MILLISECONDS) 但它只决定输入时间。

【问题讨论】:

  • 这在lock 级别上毫无意义。如果你只是在线程仍在使用它的时候释放了锁,你会得到不可预知的行为和数据竞争错误。您要做的是限制线程的允许运行时间,然后 interrupt 线程如果花费的时间太长 - 此时它应该停止工作并正确释放锁。或者查看 ExecutorService / Futures,它们可以在一定程度上帮助您实现这一目标。

标签: java multithreading locking


【解决方案1】:

这种功能不存在是有充分理由的。仅基于时间释放锁本质上是不安全的,而不考虑锁应该保护的内部状态。

虽然获取锁的超时是有意义的,但在锁的持续时间内设置超时会导致比使用时更多的麻烦。一旦你获得了锁,你可以做任何你想做的事情,直到你决定释放它。如果您遇到死锁(这种情况可能会从定时锁中获得一些用处),这很不幸,但可以通过修复您的设计而不是设置锁超时来解决。

由于您的代码只是一般的线程测试代码,我猜您只是假设存在这样的机制,但是如果您能想出需要类似的东西的情况,它可能会以不同的方式编码方式。

【讨论】:

    【解决方案2】:

    Java 提供了 Condition 类来实现类似的功能。 您使用条件类的 await() 方法,时间为 2 秒,否则调用 lock.unlock()。请记住,由于线程的固有性质,等待时间也可能大于 2 秒。此外,这很容易出错,您需要注意不同的情况。参考文档:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-21
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      相关资源
      最近更新 更多