内在锁定、客户端锁定和外在锁定之间的区别是什么?(涉及IT技术)

10

内在锁、客户端锁和外在锁有什么区别?

创建线程安全类的最佳方法是什么?

哪种类型的锁更受欢迎,为什么?


嗨,Dirk,请不要将其标记为重复。这是与其他问题不同的问题。它们没有关联。我已经单独发布了这个问题。顺便说一下,在其他发布的问题中,我还没有得到任何恰当且令人满意的答案。 - rookie_ron
3个回答

11
I would highly recommend you to read "Java Concurrency In Practice" by Brian Goetz. It is an excellent book that will help you to understand all the concepts about concurrency!
About your questions, I am not sure if I can answer them all, but I can give it a try. Most of the times, if the question is "what is the best way to lock" etc, the answer is always it depends on what problem you try to solve.
Question 1:
What you try to compare here are not exactly comparable;
Java provides a built in mechanism for locking, the synchronized block. Every object can implicitly act as a lock for purposes of synchronization; these built-in locks are called intrinsic locks.
What is interesting with the term intrinsic is that the ownership of a lock is per thread and not per method invocation. That means that only one thread can hold the lock at a given time. What you might also find interesting is the term reentrancy, which allows the same thread to acquire the same lock again. Intrinsic locks are reentrant.

客户端锁定,如果我理解的正确的话,是指不同的东西。当你没有线程安全的类时,你的客户端需要负责这个。他们需要持有锁以确保没有任何竞争条件。

外部锁定是使用显式锁来代替内置机制的同步块,它给你隐式锁以便专门使用显式锁定。这是一种更为复杂的锁定方式。它有许多优点(例如,您可以设置优先级)。一个好的起点是java documentation about locks

问题2:这取决于情况:) 对我来说最简单的方法是尽量使所有东西都不可变。当某些东西是不可变的时候,我就不需要再担心线程安全性了。

问题3: 我在你的第一个问题中回答了。


2

显式锁 - 使用并发锁定实用程序(例如Lock接口),例如- ConcurrentHashMap

内部锁 - 使用synchronized关键字进行锁定。

客户端锁定 - 类似于ConcurrentHashMap的类不支持客户端锁定,因为get方法没有使用任何类型的锁。因此,即使您在其对象上放置锁,例如synchronized(ConcurrentHashMap对象),仍然可以访问ConcurrentHashMap的对象的其他某些线程。

所有设置get方法明确或内部锁的类都支持客户端锁定。当一些客户端代码来锁定该对象时。下面是Vector的示例:

public static Object getLast(Vector list) {
    synchronized (list) {
        int lastIndex = list.size() - 1;
        return list.get(lastIndex);
    }
}

public static void deleteLast(Vector list) {
    synchronized (list) {
        int lastIndex = list.size() - 1;
        list.remove(lastIndex);
    }
}

2

以下是一些讨论不同锁定方案的链接:

显式锁定与内在锁定

客户端锁定及何时避免使用它

我不知道创建线程安全类的“最佳”方法是什么,这取决于您要实现的具体目标。通常情况下,您不必使整个类都线程安全,只需保护不同线程都可以访问的资源,如公共列表等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接