Java对象级别与类级别的同步锁synchronized语法示例

目录
  • 1.对象级别的同步锁
  • 2.类级别的同步锁
  • 3.总结

Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块。同步代码块是指同一时间只能有一个线程执行的代码,并且执行该代码的线程持有同步锁。synchronized关键字可以作用于

  • 一个代码块
  • 一种方法

当一个方法或代码块被声明为synchronized时,如果一个线程正在执行该synchronized 方法或代码块,其他线程会被阻塞,直到持有同步锁的线程释放。根据锁定的范围可以分为

  • 类级别的锁可以防止多个线程在运行时同时进入该类所有实例化对象的 synchronized代码块中。
  • 对象级别的锁可以防止多个线程在运行时同时进入当前(或某一个)实例化对象的 synchronized代码块中。

1. 对象级别的同步锁

对象级别的同步锁:当我们想要在多线程环境下同步执行一个非静态方法或非静态代码块时,在类的方法或代码块加上synchronized关键字,可以保证对象实例级别数据的线程安全。(比较后文的类级别的同步锁,回头来理解这句话)

对象级别的加锁的代码如下,如:在方法上加锁,锁对象为当前类的实例化对象

public class DemoClass{
	public synchronized void demoMethod(){}
}

如:为代码块加锁,锁对象为this对象

public class DemoClass{
	public void demoMethod(){
		synchronized (this){
			//同步代码块
		}
	}
}

如:为代码块加锁,锁对象为我们创建的任意一个对象。不要使用非final的成员变量作为同步锁对象,因为非final成员变量可以被重新赋值,导致不同的线程使用不同的对象作为锁,达不到同步锁定的效果。

public class DemoClass{
    //注意这里的关键字final非常重要,看说明
	private final Object lock = new Object();
	public void demoMethod(){
		synchronized (lock){
			//同步代码块
		}
	}
}

2. 类级别的同步锁

类级别的锁可以防止多个线程在运行时进入该类所有实例化对象的 "synchronized块中。也就是说如果运行时有100个DemoClass的实例,那么每次只有一个线程能够在任何一个实例中执行demoMethod(),所有其他实例的所有其他线程都被锁定。

为了保障静态数据线程安全,应该使用类级别的锁定。我们知道static关键字将方法的数据关联到类的级别上,所以在静态方法上使用锁。

静态方法加锁,对该类所有的实例化对象生效

public class DemoClass{
	//静态方法加锁,对该类所有的实例化对象生效
	public synchronized static void demoMethod(){
	}
}

获取 .class类的引用,类级别的锁

public class DemoClass{
	public void demoMethod(){
		//获取 .class类的引用,类级别的锁,对该类所有的实例化对象生效
		synchronized (DemoClass.class){
			//同步代码块
		}
	}
}

使用静态对象的锁,类级别的锁

public class DemoClass{
    //静态对象,类级别,注意这里的关键字final非常重要
	private final static Object lock = new Object();
	public void demoMethod(){
		//使用静态对象的锁,类级别锁,对该类所有的实例化对象生效
		synchronized (lock){
			//同步代码块
		}
	}
}

3. 总结

  • Java中的同步机制保证了两个或多个线程无法同时执行一个需要相同同步锁的方法。
  • "synchronized "关键字只能用于方法和代码块。这些方法或代码块可以是静态或非静态的。
  • 当一个线程进入synchronized方法或代码块时,它就会获得一个锁,当它离开同步方法或代码块时,它就会释放这个锁。如果线程执行过程出现任何错误或异常,锁也会被释放。
  • 使用"synchronized "关键字持有的锁在本质上是可重入的,这意味着如果一个同步方法调用另一个使用相同锁的同步方法,那么持有锁的当前线程可以进入该方法而无需再次获得锁。
  • 如果同步块中使用的对象为空,Java synchronized 将抛出NullPointerException
  • 使用synchronized同步方法会给你的应用程序带来性能成本。因此,尽量在绝对需要的情况下才使用同步。另外优先考虑使用同步代码块,并且只同步代码的关键部分。
  • 静态同步方法和非静态同步方法有可能同时或并发运行,因为它们使用的是不同的锁。
  • 根据Java语言规范,你不能在构造函数中使用synchronized关键字。这是不合法的,会导致编译错误。
  • 不要使用非final的成员变量作为同步锁对象,因为非final成员变量可以被重新赋值,导致不同的线程使用不同的对象作为锁,达不到同步锁定的效果。
  • 不要使用字符串字面量作为锁对象,如:String a = "1";,因为它们可能会被应用程序中的其他地方引用,并可能导致死锁。用new关键字创建的字符串对象可以安全使用。

以上就是Java对象级别与类级别的同步锁synchronized语法示例的详细内容,更多关于Java对象与类级别同步锁synchronized的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java中synchronized正确使用方法解析

    生活中随处可见并行的例子,并行 顾名思义就是一起进行的意思,同样的程序在某些时候也需要并行来提高效率,在上一篇文章中我们了解了 Java 语言对缓存导致的可见性问题.编译优化导致的顺序性问题的解决方法,下面我们就来看看 Java 中解决因线程切换导致的原子性问题的解决方案 -- 锁 . 说到锁我们并不陌生,日常工作中也可能经常会用到,但是我们不能只停留在用的层面上,为什么要加锁,不加锁行不行,不行的话会导致哪些问题,这些都是在使用加锁语句时我们需要考虑的. 来看一个使用 32 位的 CPU 写

  • JAVA面试题 简谈你对synchronized关键字的理解

    面试官:sychronized关键字有哪些特性? 应聘者: 可以用来修饰方法; 可以用来修饰代码块; 可以用来修饰静态方法; 可以保证线程安全; 支持锁的重入; sychronized使用不当导致死锁; 了解sychronized之前,我们先来看一下几个常见的概念:内置锁.互斥锁.对象锁和类锁. 内置锁 在Java中每一个对象都可以作为同步的锁,那么这些锁就被称为内置锁.线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁.获得内置锁的唯一途径就是进入这个锁的保护的同

  • Java synchronized锁升级jol过程详解

    jol(java object layout)需要的依赖 <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.10</version> </dependency> 一.synchronized锁对象的升级(膨胀)过程主要如下: 1.膨胀过程:无锁(锁对象初始化时)-> 偏向

  • Java Synchronized锁失败案例及解决方案

    synchronized关键字,一般称之为"同步锁",用它来修饰需要同步的方法和需要同步代码块,默认是当前对象作为锁的对象. 同步锁锁的是同一个对象,如果对象发生改变,则锁会不生效. 锁失败的代码: public class IntegerSynTest { //线程实现Runnable接口 private static class Worker implements Runnable{ private Integer num; public Worker(Integer num){

  • 浅谈Synchronized和Lock的区别

    如下所示: Synchronized是内置的java关键字,Lock是一个java类. Synchronized无法判断是否获取到了锁,Lock可以判断是否获取到了锁. Synchronized会自动释放锁,Lock必须手动释放锁. Synchronized线程1获得锁之后阻塞,等待锁的线程2会一直等下去(死等).Lock不一定会死等. Synchronized可重入锁.不可中断.非公平锁.Lock是可重入锁.选择是否可中断.可以选择是否公平. Synchronized适合锁少量的代码同步问题.

  • Java使用synchronized实现互斥锁功能示例

    本文实例讲述了Java使用synchronized实现互斥锁功能.分享给大家供大家参考,具体如下: 代码 package per.thread; import java.io.IOException; public class Test { private int i = 0; private Object object = new Object(); public static void main(String[] args) throws IOException { Test test =

  • java中SynchronizedList和Vector的区别详解

    前言 Vector是java.util包中的一个类. SynchronizedList是java.util.Collections中的一个静态内部类. 在多线程的场景中可以直接使用Vector类,也可以使用Collections.synchronizedList(List list)方法来返回一个线程安全的List. 那么,到底SynchronizedList和Vector有没有区别,为什么java api要提供这两种线程安全的List的实现方式呢? 首先,我们知道Vector和Arraylis

  • Java线程安全解决方案(synchronized,ReentrantLock,Atomic)

    线程安全解决方案 synchronized,ReentrantLock,Atomic 使用场景描述 在实际开发过程中如果服务量,请求频繁,就会经常碰见并发,这时候不做处理就会出现很多非法数据.这时候就需要解决线程安全的问题,这时候就可以使用java当中的锁机制.常用有java关键synchronized.可重入锁ReentrantLock,还有并发包下的Atomic 或者Concurrent的安全类型. synchronized使用场景: 在资源竞争不是很激烈的情况下,偶尔出现并发,需要同步的情

  • Java对象级别与类级别的同步锁synchronized语法示例

    目录 1.对象级别的同步锁 2.类级别的同步锁 3.总结 Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块.同步代码块是指同一时间只能有一个线程执行的代码,并且执行该代码的线程持有同步锁.synchronized关键字可以作用于 一个代码块 一种方法 当一个方法或代码块被声明为synchronized时,如果一个线程正在执行该synchronized 方法或代码块,其他线程会被阻塞,直到持有同步锁的线程释放.根据锁定的范围可以分为 类级别的锁可以防止多个线程

  • Java 对象深拷贝工具类的实现

    目录 1. 使用场景 1.1 场景一 1.2 场景二 2. Spring 中的对象拷贝 3. 本工具类中的对象拷贝 3.1 拷贝对象本身(单个) 3.2 拷贝对象本身(批量) 3.3 拷贝对象属性至其他类(单个) 3.4 拷贝对象属性至其他类(批量) 4. 工具类源码 1. 使用场景 我们在Java编码中,有时候可能会经常遇到对象拷贝的场景. 1.1 场景一 当我们更新一个对象的时候,如果要记录对象属性的前后变化,那么在更新对象之前,我们应该首先将对象拷贝暂存起来,且这个时候的拷贝一定是深拷贝(

  • Java同步锁Synchronized底层源码和原理剖析(推荐)

    目录 1 synchronized场景回顾 2 反汇编寻找锁实现原理 3 synchronized虚拟机源码 3.1 HotSpot源码Monitor生成 3.2 HotSpot源码之Monitor竞争 3.3 HotSpot源码之Monitor等待 3.4 HotSpot源码之Monitor释放 1 synchronized场景回顾 目标:synchronized回顾(锁分类–>多线程)概念synchronized:是Java中的关键字,是一种同步锁.Java中锁分为以下几种:乐观锁.悲观锁(

  • Java 同步锁(synchronized)详解及实例

    Java 同步锁(synchronized)详解及实例 Java中cpu分给每个线程的时间片是随机的并且在Java中好多都是多个线程共用一个资源,比如火车卖票,火车票是一定的,但卖火车票的窗口到处都有,每个窗口就相当于一个线程,这么多的线程共用所有的火车票这个资源.如果在一个时间点上,两个线程同时使用这个资源,那他们取出的火车票是一样的(座位号一样),这样就会给乘客造成麻烦.比如下面程序: package com.pakage.ThreadAndRunnable; public class Ru

  • PHP pthreads v3下同步处理synchronized用法示例

    本文实例讲述了PHP pthreads v3下同步处理synchronized用法.分享给大家供大家参考,具体如下: 之所以会用到同步,是因为如果多个线程中对同一个资源进行操作时,会发生混乱. 比如2个线程对变量进行加1操作,第1个线程还没来的及改写数据时,第2个线程就对变量进行操作了,那变量最终的结果就是未知的,这个时候就需要同步来进行控制了. 例子如下: <?php class Count extends Thread { public $cnt = 0; public function r

  • 一篇文章带你深入了解Java对象与Java类

    目录 1.面向对象是什么? 2.Java类 1.什么是类 2.Java类 类的结构 Java类的格式 3.java对象 4.类和对象 5.类中的变量,方法 1.变量分类 成员变量: 局部变量: 2.方法分类 6.方法重载 7.对象与引用 基本类型和引用类型的区别: 值传递与引用传递 8.static关键字 概念 static属性 static方法 代码块 9.类的加载执行 10.包 包的概念: 包的作用: 包(package)的命名规范: 访问权限修饰符 11.面向对象语言的三大特征 1.封装

  • Java操作集合工具类Collections使用详解

    这篇文章主要介绍了java操作集合工具类Collections使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Collections是一个操作Set.List和Map等集合的工具类. Collections中提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了对集合对象设置不可变.对集合对象实现同步控制等方法. 排序操作: reverse(List):反转List中元素的顺序: shuffle(List):对List集合元素进行

  • Java中自定义注解类及使用实例解析

    这篇文章主要介绍了Java中自定义注解类并使用过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在Java框架中,经常会使用注解,而且还可以省很多事,来了解下自定义注解. 注解是一种能被添加到java代码中的元数据,类.方法.变量.参数和包都可以用注解来修饰.注解对于它所修饰的代码并没有直接的影响 先写一个自己的注解类 @Documented //会被javadoc命令识别 @Retention(RetentionPolicy.RUNTI

  • Java Spring事务的隔离级别详解

    目录 引言 数据库访问的并发性问题 事务的隔离级别 悲观锁和乐观锁 总结 引言 之前关于事务的文章已介绍了事务的概念以及事务的四个属性(ACID),相信你对事务应该有所认识和了解. 本篇文章是关于事务的隔离性,介绍数据库提供的多种隔离级别. 数据库访问的并发性问题 所谓事务的隔离性,其实事务的这个属性是针对数据库访问的并发性问题而言的. 那何谓数据库访问的并发性问题呢? 所谓数据库访问的并发性问题是指多个事务可以同时访问数据库中的数据,而当多个事务在数据库中并发执行(同时执行)时,数据的一致性可

  • 详解java 对象锁与类锁

    一.什么是对象锁 对象锁也叫方法锁,是针对一个对象实例的,它只在该对象的某个内存位置声明一个标识该对象是否拥有锁,所有它只会锁住当前的对象,而并不会对其他对象实例的锁产生任何影响,不同对象访问同一个被synchronized修饰的方法的时候不会阻塞, 例如: public class MyObject { private synchronized void method1(){ try { System.out.println(Thread.currentThread().getName());

随机推荐