在 Java 中,同步 代码块一次只能由一个线程执行。另外,java支持多线程并发执行。这可能会导致两个或多个线程同时访问相同的字段或对象。
同步是使执行中的所有并发线程保持同步的过程。同步避免了由于共享内存视图不一致而导致的内存一致性错误。当方法声明为同步时;该线程持有该方法对象的监视器或锁定对象。如果另一个线程正在执行 synchronized 方法,您的线程将被阻塞,直到该线程释放监视器。
请注意,我们可以在定义的方法或块的类中使用 synchronized
关键字。 synchronized
关键字不能与类定义中的变量或属性一起使用。
对象级锁是一种机制,当我们想要同步一个非静态方法或非静态代码块时,只有一个线程能够在类的给定实例上执行代码块。应始终这样做以使实例级数据线程安全。
对象级锁定可以按如下方式完成:
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 } } }
类级别锁 可防止多个线程在运行时进入该类所有可用实例中的任何一个的synchronized
块中。这意味着如果在运行时有 100 个 DemoClass
实例,那么一次只有一个线程能够在任何一个实例中执行 demoMethod()
,并且所有其他实例都将被其他线程锁定。
应始终执行类级锁定以使静态数据线程安全。我们知道 static 关键字将方法的数据关联到类级别,因此在静态字段或方法上使用锁定使其在类级别。
public class DemoClass { //Method is static public synchronized static void demoMethod(){ } } or public class DemoClass { public void demoMethod() { //Acquire lock on .class reference synchronized (DemoClass.class) { //other thread safe code } } } or public class DemoClass { private final static Object lock = new Object(); public void demoMethod() { //Lock object is static synchronized (lock) { //other thread safe code } } }
synchronized
关键字只能与方法和代码块一起使用。这些方法或块可以是静态或非静态。synchronized
方法或阻塞时,它会获得一个锁,而每当它离开同步方法或阻塞时,它就会释放锁。即使线程在完成后或由于任何错误或异常而离开同步方法,锁也会被释放。synchronized
关键字本质上是可重入 这意味着如果一个同步方法调用另一个需要相同锁的同步方法,那么持有锁的当前线程可以在不获取锁的情况下进入该方法。NullPointerException
。例如,在上面的代码示例中,如果锁被初始化为 null,则“synchronized (lock)
”将抛出 NullPointerException
。synchronized
关键字。这是非法的,会导致编译错误。new
关键字创建的字符串对象。但作为最佳实践,创建一个新的 private 作用域 Object
实例或锁定我们要保护的共享变量本身。 [感谢 Anu 在评论中指出这一点。]让我知道有关 Java 中对象级锁与类级锁的想法和疑问。
快乐学习!!
地址:https://www.cundage.com/article/object-vs-class-level-locking.html