我在许多关于可重入锁的教程中看到,它们创建一个新的可重入锁并注入资源,可重入锁的锁定和解锁在try/finally块中调用。我不理解这个锁和线程中使用的资源之间的连接。下面是一个关于可重入锁的教程示例
资源代码
public class Resource {
public void doSomething(){
//do some operation, DB read, write etc
}
public void doLogging(){
//logging, no need for thread safety
}
}
线程声明代码中使用的资源
public class ConcurrencyLockExample implements Runnable{
private Resource resource;
private Lock lock;
public ConcurrencyLockExample(Resource r){
this.resource = r;
this.lock = new ReentrantLock();
}
@Override
public void run() {
try {
if(lock.tryLock(10, TimeUnit.SECONDS)){
resource.doSomething();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
//release lock
lock.unlock();
}
resource.doLogging();
}
}
有人能解释一下,这是如何防止多个线程同时访问给定的资源,从而导致争用情况的???这个可重入锁是在资源中创建对象级锁还是类级锁???
在某种意义上,可重入锁既不是类级锁,也不是对象级锁。从更实际的意义上讲,这与它们中的任何一个都是一样的。
实际上,您应该忘记“类级”和“对象级”锁定。这些都不是有用的区别。
您可以在同步(锁){…}中使用任何对象作为锁 块。“对象级”锁定仅仅意味着,在类C的某个方法中,您选择的对象是该类的一个实例;“class level”表示您选择使用C.class作为锁对象。
但是,您也可以使用其他对象,*和同步(锁定)的行为方式与为锁定选择的对象相同。
*这是一种经验丰富的软件开发人员经常使用的模式:
class C {
private final Object lock = new Object();
public MyType myMethod(...) {
...
synchronized(lock) {
...
}
...
}
}
在上述私有
对象而不是C
的实例上同步的优势是微妙的。简而言之,它可以防止使用类C
的某些应用程序的作者使用C
的实例作为锁。如果两个不同的作者选择使用同一个实例作为锁,可能会出现不可预见的交互(例如,在最坏的情况下,死锁。)
问题内容: 我一直在研究Java多线程概念。我越经历他们,我就越困惑。 现在,我还不了解Java中的类级别,对象级别,显式和固有锁定之间的区别。有人可以让我知道这是什么吗?另外,如果我可以理解一些示例,那对我也将非常有帮助。 问题答案: 显式与内在 当您在对象上使用或间接用作方法签名的一部分时,您正在创建内部锁。您依赖与所有对象和类关联的内置锁。 软件包中的Java 5+提供了显式锁。最常用的类可
我一直在研究Java多线程概念。我看得越多,就越困惑。 现在我不明白Java中类级别、对象级别、显式锁定和内在锁定之间的区别。有人能告诉我是什么吗?此外,如果我能得到一些例子来理解,那将对我很有帮助。
主要内容:一、简介,二、Java对象头中的Mark Word,三、偏向锁,四、轻量级锁,五、重量级锁,六、自旋锁,七、锁升级过程一、简介 在讲解这些锁概念之前,我们要明确的是这些锁不等同于Java API中的ReentratLock这种锁,这些锁是概念上的,是JDK1.6中为了对synchronized同步关键字进行优化而产生的的锁机制。这些锁的启动和关闭策略可以通过设定JVM启动参数来设置,当然在一般情况下,使用JVM默认的策略就可以了。 二、Java对象头中的Mark Word HotSpo
为什么java可重入锁不会导致死锁?
主要内容:1 什么是Java可重入锁,2 Java可重入锁的优势,3 Java可重入锁的例子1 什么是Java可重入锁 根据Sun公司的说法,Java锁是可重入的,这意味着,如果从方法中调用方法,则Java线程可以将同一把锁用于不同的同步方法。 2 Java可重入锁的优势 它避免了单线程死锁。 3 Java可重入锁的例子 让我们通过以下示例了解Java可重入锁: 在此类中,m和n是同步方法。m() 方法在内部调用n() 方法。 现在让我们在线程上调用m() 方法。在下面给出的类中,我们使