将synchronized() 与ReentrantLock.lock() 混合使用

发布于 2024-09-03 04:15:49 字数 549 浏览 7 评论 0原文

在 Java 中,ReentrantLock.lock()ReetrantLock.unlock() 使用与 synchronized() 相同的锁定机制吗?

我的猜测是“不”,但我希望我是错的。

示例:

假设线程 1 和线程 2 都可以访问:

ReentrantLock lock = new ReentrantLock();

线程 1 运行:

synchronized (lock) {
    // blah
}

线程 2 运行:

lock.lock();
try {
    // blah
}
finally {
    lock.unlock();
}

假设线程 1 首先到达其部分,然后线程 2 在线程 1 完成之前到达:线程 2 是否会等待线程 1 离开 < code>synchronized() 块,还是会继续运行?

In Java, do ReentrantLock.lock() and ReetrantLock.unlock() use the same locking mechanism as synchronized()?

My guess is "No," but I'm hoping to be wrong.

Example:

Imagine that Thread 1 and Thread 2 both have access to:

ReentrantLock lock = new ReentrantLock();

Thread 1 runs:

synchronized (lock) {
    // blah
}

Thread 2 runs:

lock.lock();
try {
    // blah
}
finally {
    lock.unlock();
}

Assume Thread 1 reaches its part first, then Thread 2 before Thread 1 is finished: will Thread 2 wait for Thread 1 to leave the synchronized() block, or will it go ahead and run?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风月客 2024-09-10 04:15:49

不,即使线程 1 在同一个锁上同步,线程 2 也可以lock()。这是文档的内容不得不说:

请注意,Lock 实例只是
普通物体,它们本身可以是
用作同步中的目标
陈述。获取监视器锁
Lock实例没有指定
与调用任何一个的关系
该实例的 lock() 方法。它
建议避免混淆
你从来没有在这使用 Lock 实例
方式,除了在他们自己的范围内
实施。

No, Thread 2 can lock() even when Thread 1 is synchronized on the same lock. This is what the documentation has to say:

Note that Lock instances are just
normal objects and can themselves be
used as the target in a synchronized
statement. Acquiring the monitor lock
of a Lock instance has no specified
relationship with invoking any of the
lock() methods of that instance. It
is recommended that to avoid confusion
you never use Lock instances in this
way, except within their own
implementation.

天生の放荡 2024-09-10 04:15:49

两种机制不同。实现/性能方面:

  • 同步机制使用“内置”到 JVM 中的锁定机制;底层机制取决于特定的 JVM 实现,但通常使用原始 compare-and- 的组合设置操作(CAS)指令,适用于锁不竞争的情况,加上操作系统提供的底层锁定机制;
  • 像 ReentrantLock 这样的锁类基本上是用纯 Java 编写的(通过 Java 5 中引入的一个库,该库向 Java 公开了 CAS 指令和线程调度),因此在操作系统上更加标准化并且更可控(见下文)。

在某些情况下,显式锁可以表现得更好。如果您查看我在 Java 5 下执行的锁定机制比较,您会看到在该特定测试(多个线程访问数组)中,以“不公平”模式配置的显式锁定类(黄色和青色三角形)比普通同步(紫色箭头)允许更高的吞吐量。

(我还应该说,synchronized 的性能在最新版本的 Hotspot 中得到了改进;在最新版本或其他情况下可能没有太多改进 - 这显然是一种环境下的测试。)

功能 -明智的:

  • 同步机制提供了最少的功能(您可以锁定和解锁,锁定是一种全有或全无的操作,您更容易受到操作系统编写者决定的算法的影响),尽管具有内置语法和JVM 中内置的一些监控;
  • 显式锁类提供了更多控制,特别是您可以指定“公平”锁、超时锁、覆盖(如果您需要更改锁的行为)...

The two mechanisms are different. Implementation/performance wise:

  • the synchronized mechanism uses a locking mechanism that is "built into" the JVM; the underlying mechanism is subject to the particular JVM implementation, but typically uses a combination of a raw compare-and-set operation (CAS) instruction for cases where the lock isn't contended plus underlying locking mechanisms provided by the OS;
  • the lock classes such as ReentrantLock are basically coded in pure Java (via a library introduced in Java 5 which exposes CAS instructions and thread descheduling to Java) and so is somewhat more standardised across OS's and more controllable (see below).

Under some circumstances, the explicit locks can perform better. If you look at this comparison of locking mechanisms I performed under Java 5, you'll see that in that particular test (multiple threads accessing an array), explicit lock classes configured in "unfair" mode (the yellow and cyan triangles) allow more throughput than plain synchronized (the purple arrows).

(I should also say that the performance of synchronized has been improved in more recent versions of Hotspot; there may not be much in it on the latest versions or indeed under other circumstances-- this is obviously one test in one environment.)

Functionality-wise:

  • the synchronized mechanism provides minimal functionality (you can lock and unlock, locking is an all-or-nothing operation, you're more subject to the algorithm the OS writers decided on), though with the advantage of built-in syntax and some monitoring built into the JVM;
  • the explicit lock classes provide more control, notably you can specify a "fair" lock, lock with a timeout, override if you need to alter the lock's behiour...
苦行僧 2024-09-10 04:15:49

为什么在 Account 类中将余额设为静态?
消除静电,它应该可以工作。

另外,对您的线程使用有疑问。在 TestMain 中,您创建新线程并分配可运行对象,例如 WithdrawRequests &存款请求。但您再次在这些可运行对象的构造函数中创建新线程。这会导致run方法被执行两次!

Why did you make the balance static in Account class?
Remove static and it should work.

Also, have a question about your thread usage. In your TestMain you create new threads and assign runnables like WithdrawRequests & DepositRequests. But again you create new threads inside the constructors of those runnables. This will cause the run method to be executed twice!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文