我一直在研究Java多线程概念。我经历的越多,我就越困惑。
现在我不了解Java中的类级别,对象级别,显式锁定和内部锁定之间的差异。有人可以让我知道这是什么?另外,如果我能得到一些例子来理解,那对我来说非常有帮助。
答案 0 :(得分:2)
当您在对象上使用synchronized
或作为方法签名的一部分间接使用时,您正在创建intrinsic lock。您依赖与所有对象和类关联的内置锁。
包java.util.concurrent.locks
中的Java 5+中提供了显式锁定。最常用的类可能是ReentrantLock
。这些提供了使用内部锁定的替代方法,并提供了内部锁定无法实现的功能。
这种区别仅适用于内在锁。如果您有synchronized static method,则使用的内部锁定将与类对象本身相关联。如果在对象实例上进行同步(或具有同步的实例方法),则它将是对象级锁定。
Brian Goetz的Java Concurrency in Practice是一本很好的书,用于理解Java中多线程编程的混乱世界。
答案 1 :(得分:1)
使用“同步”关键字时,它会使用内部锁定或监视器。 Java中的每个对象都有一个与之关联的内部锁。每当线程尝试访问 同步块或方法 时,它就会获取本机锁或该对象上的监视器或对象级锁定。对于 静态方法 ,线程获取锁定类对象。
public synchronized void doAtomicTransfer(){
//enter synchronized block , acquire lock over this object.
operation1()
operation2();
} // exiting synchronized block, release lock over this object.
内在锁定机制可能有一些功能限制,例如:
Explicit locks 非常有用。特别是,它们具有以下特征:
答案 2 :(得分:0)
"类级"锁定,"对象级"锁定是一种人为的想法,由作者创建,他们可能对Java的内在锁定无法有深入的了解。
类级别锁定如下所示:
class Foobar {
static synchronized void moo() { ... }
}
但这种结构实际上只是一种写作的简写方式:
class Foobar {
static void moo() {
synchronized (Foobar.class) { ... }
}
}
对象级锁定,如下所示:
class Foobar {
synchronized void baa() { ... }
}
只是简写:
class Foobar {
static void baa() {
synchronized (this) { ... }
}
}
所以真的,在"班级"和"对象级"锁定,只有一个概念,synchronized
块:
synchronized(objectReference) {...}
您需要知道的是,JVM不允许多个线程同时在同一个对象上进行同步。
当您要保护的数据是全局数据时,在访问数据时同步全局单例对象是有意义的。 Foobar.class
是一个全球性的单身人士。
当您想要保护的数据完全包含在某个对象实例中时,在与该实例关联的内容上或在实例本身(即this
)上进行同步是有意义的。
答案 3 :(得分:-1)
当您想要同步非静态方法或非静态代码块时,对象级锁定是一种机制,这样只有一个线程能够在给定的类实例上执行代码块。应始终这样做以使实例级数据线程安全。
public class DemoClass
{
public synchronized void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (this)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
}
类级别锁定可防止多个线程在运行时的所有可用实例中的同步块中输入。这意味着如果在运行时有100个DemoClass实例,那么一次只有一个线程可以在任何一个实例中执行demoMethod(),并且其他所有实例都将被锁定用于其他线程。应始终这样做以使静态数据线程安全。
public class DemoClass
{
public synchronized static void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (DemoClass.class)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final static Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
}