为什么使用ReentrantLock如果可以使用synchronized(this)? [英] Why use a ReentrantLock if one can use synchronized(this)?

查看:235
本文介绍了为什么使用ReentrantLock如果可以使用synchronized(this)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果你可以使用 synchronized(this),我想了解什么使得锁的并发性非常重要。在下面的虚拟代码中,我可以做:

I'm trying to understand what makes the lock in concurrency so important if one can use synchronized (this). In the dummy code below, I can do either:


  1. 同步整个方法或同步易受攻击的区域。})

  2. 使用ReentrantLock锁定易受攻击的代码区域。

/ p>

Code:

private final ReentrantLock lock =  new ReentrantLock(); 
    private static List<Integer> ints;

    public Integer getResult(String name) { 
        .
        .
        .
        lock.lock();
        try{
            if (ints.size()==3) {
                ints=null;
                return -9;
            }   

            for (int x=0; x<ints.size(); x++) {
                System.out.println("["+name+"] "+x+"/"+ints.size()+". values >>>>"+ints.get(x));
            }

        }finally {
            lock.unlock();
        } 
        return random;
}


推荐答案

A ReentrantLock 是非结构化的,与<$ c不同$ c> synchronized 构造 - 即,您不需要使用块结构进行锁定,甚至可以跨方法保持锁定。例如:

A ReentrantLock is unstructured, unlike synchronized constructs -- i.e. you don't need to use a block structure for locking and can even hold a lock across methods. An example:

private ReentrantLock lock;

public void foo() {
  ...
  lock.lock();
  ...
}

public void bar() {
  ...
  lock.unlock();
  ...
}

这种流程不可能通过单个监视同步构造。

Such flow is impossible to represent via a single monitor in a synchronized construct.

code> ReentrantLock 支持锁定轮询可中断锁等待支持超时 ReentrantLock 也支持可配置的公平性政策,允许更灵活的线程调度。

Aside from that, ReentrantLock supports lock polling and interruptible lock waits that support time-out. ReentrantLock also has support for configurable fairness policy, allowing more flexible thread scheduling.


此类的构造函数接受可选的公平参数。当设置 true 时,在争用下,锁优先授予访问最长等待线程的权限。否则,此锁不保证任何特定的访问顺序。使用由许多线程访问的公平锁的程序可以显示比使用默认设置的那些更低的总吞吐量(即,更慢,通常慢得多),但是在获得锁和保证缺乏饥饿的时间上具有更小的变化。然而,请注意,锁的公平性不保证线程调度的公平性。因此,使用公平锁的许多线程中的一个可以连续获得它多次,而其他活动线程不进行并且当前不持有锁。另请注意,未定义的 tryLock 方法不符合公平设置。如果锁定可用,即使其他主题正在等待,也会成功。

The constructor for this class accepts an optional fairness parameter. When set true, under contention, locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order. Programs using fair locks accessed by many threads may display lower overall throughput (i.e., are slower; often much slower) than those using the default setting, but have smaller variances in times to obtain locks and guarantee lack of starvation. Note however, that fairness of locks does not guarantee fairness of thread scheduling. Thus, one of many threads using a fair lock may obtain it multiple times in succession while other active threads are not progressing and not currently holding the lock. Also note that the untimed tryLock method does not honor the fairness setting. It will succeed if the lock is available even if other threads are waiting.






code> ReentrantLock 可能也可以 更多可扩展 ,在更高的争用下表现更好。您可以在此此处了解详情。


ReentrantLock may also be more scalable, performing much better under higher contention. You can read more about this here.

然而,这项索赔受到质疑;请参阅以下注释:

This claim has been contested, however; see the following comment:


在可重入锁定测试中,每次都创建一个新的锁定,因此没有排他锁定,数据无效。此外,IBM链接不提供底层基准的源代码,因此不可能表明测试是否正确执行。

In the reentrant lock test, a new lock is created each time, thus there is no exclusive locking and the resulting data is invalid. Also, the IBM link offers no source code for the underlying benchmark so its impossible to characterize whether the test was even conducted correctly.






何时使用 ReentrantLock s?根据那篇developerWorks文章...


When should you use ReentrantLocks? According to that developerWorks article...


答案很简单 - 当你真正需要它提供的东西时使用 synchronized 没有,像定时锁等待,可中断锁等待,非块结构锁,多个条件变量或锁定轮询。 ReentrantLock 也有可扩展性的好处,如果你实际上有一个展示高争用的情况,你应该使用它,但要记住绝大多数 synchronized 块几乎没有展示任何争用,更不用说高争用。我建议同步开发,直到同步被证明是不适当的,而不是简单地假设性能会更好,如果你使用 ReentrantLock 。请记住,这些是高级用户的高级工具。 (和真正的高级用户倾向于喜欢他们可以找到的最简单的工具,直到他们相信简单的工具是不够的。)一如既往,使它正确的,然后担心是否必须加快它。 p>

The answer is pretty simple -- use it when you actually need something it provides that synchronized doesn't, like timed lock waits, interruptible lock waits, non-block-structured locks, multiple condition variables, or lock polling. ReentrantLock also has scalability benefits, and you should use it if you actually have a situation that exhibits high contention, but remember that the vast majority of synchronized blocks hardly ever exhibit any contention, let alone high contention. I would advise developing with synchronization until synchronization has proven to be inadequate, rather than simply assuming "the performance will be better" if you use ReentrantLock. Remember, these are advanced tools for advanced users. (And truly advanced users tend to prefer the simplest tools they can find until they're convinced the simple tools are inadequate.) As always, make it right first, and then worry about whether or not you have to make it faster.

这篇关于为什么使用ReentrantLock如果可以使用synchronized(this)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆