synchronized关键字  

  synchronized关键字最主要的三种使用方式的总结

  1.修饰实例方法,作用于当前对象实例加锁,进入同步代码块前要获得当前对象实例的锁

  2.修饰静态方法,作用于当前类对象加锁,进入同步代码块前要获得当前类对象的锁。也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例

  对象,是类成员(static表明这是该类的一个静态资源,不管new了多少个对象,只有这一份),如果一个线程A调用一个实例对象的非静态synchronized方法,而线程B调用

  这个实例对象所属类的静态synchronized方法,是允许的,不会发生互斥现象。因为访问静态的synchronized方法占用的锁是当前类的锁,访问非静态的synchronized方法

  占用的锁是当前实例对象的锁。

  3.修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码块前要获得给定对象的锁。和synchronized方法一样,synchronized(this)代码块也是锁定当前对象的。

  synchronized关键字加到static方法和synchronized(class)代码块上都是都是给class类上锁。再提一下,synchronized关键字非静态方法上是给当前对象实例加锁,另外需要

  注意的是,尽量不要使用synchronized(String a)因为JVM中字符串常量池具有缓冲功能。

  双重校验锁实现对象单例

public class Singleton {

    private volatile static Singleton singleton;

    private Singleton(){}

    public static Singleton getSingleton(){
if (singleton==null){
synchronized (Singleton.class){
if (singleton==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}

  需要注意的是singleton对象使用volatile关键字修饰原因如下:

  singleton = new Singleton(); 这段代码其实分为三步执行,第一步为singleton分配内存空间,第二步初始化singleton,第三部将singleton指向分配的内存地址,但是由于

  JVM具有指令重排的特征,执行顺序有可能变成第一步->第三步->第二步,此指令重排在单线程环境下没有问题,但是在多线程环境下会导致某个线程获得还没有初始化

  的实例。例如线程1执行了第一步和第三步,此时线程2调用getSingleton()方法发现singleton并不为空,因此返回singleton,但此时singleton还未初始化。使用volatile

  关键字可以禁止JVM的指令重排,保证在多线程环境下正常运行。

  synchronized关键字和volatile关键字的区别

  把变量声明为volatile,当一个线程在工作内存中修改该变量的值之后会立即将值同步到主内存,同时使其他线程的工作内存缓存的原始值无效,另一个线程需要使用

  这个变量时,需要重新从主内存读取该变量值到自己的工作内存,保证了变量的可见性,还有一个作用是防止指令重排序。

  区别有以下几点:

    1.volatile关键字是线程同步的轻量级实现,所以volatile关键字的性能肯定要比synchronized关键字要好,但是volatile关键字只能用于变量,而synchronized关键字可以

    修饰方法和代码块。在JDK1.6之后进行了获得锁和释放锁带来的性能消耗的优化,相对来说synchronized关键字使用场景较多一点

    2.多线程访问volatile关键字不会发生阻塞,synchronized可能会发生阻塞

    3.volatile关键字能保证数据的可见性,但不能保证数据的原子性,synchronized关键字两者都能保证

    4.volatile关键字主要用于解决变量在多个线程之间的可见性,synchronized关键字解决的是多个线程之间访问资源的同步性

  

并发编程之synchronized关键字的更多相关文章

  1. Java并发编程之synchronized关键字

    整理一下synchronized关键字相关的知识点. 在多线程并发编程中synchronized扮演着相当重要的角色,synchronized关键字是用来控制线程同步的,可以保证在同一个时刻,只有一个 ...

  2. Java 多线程并发编程之 Synchronized 关键字

    synchronized 关键字解析 同步锁依赖于对象,每个对象都有一个同步锁. 现有一成员变量 Test,当线程 A 调用 Test 的 synchronized 方法,线程 A 获得 Test 的 ...

  3. 高并发编程之synchronized

    一.什么是线程? 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程 ...

  4. Java并发编程之volatile关键字解析

    一内存模型的相关概念 二并发编程中的三个概念 三Java内存模型 四深入剖析volatile关键字 五使用volatile关键字的场景 volatile这个关键字可能很多朋友都听说过,或许也都用过.在 ...

  5. 并发编程之synchronized锁(一)

    一.设计同步器的意义 多线程编程中,有可能会出现多个线程同时访问同一个共享.可变资源的情况,这个资源我们称之其为临界资源:这种资源可能是:对象.变量.文件等. 共享:资源可以由多个线程同时访问 可变: ...

  6. Java并发编程之volatile关键字

    大概是因为项目.业务的原因,工作上几乎还没有使用过多线程相关的功能,相关知识差不多都忘了,所以最近补一下基础. volatile用来修饰共享变量,volatile变量具有 synchronized 的 ...

  7. Java 并发编程之volatile关键字解析

    摘录 1. 计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入.由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执 ...

  8. Java并发编程之synchronized

    在Java编程中,为了保证线程安全,有3种不同的思路1.互斥同步:包括synchronized和lock等. 2.非阻塞同步:如AtomicInteger的increaseAndGet()方法等. 3 ...

  9. 并发编程之synchronized(二)------jvm对synchronized的优化

    一.锁的粗化 看如下代码 public class Test { StringBuffer stb = new StringBuffer(); public void test1(){ //jvm的优 ...

随机推荐

  1. vue原生table合并单元格并可编辑

    <template> <div> <div class="el-card box-card table_container"> <div ...

  2. 芯灵思Sinlinx A64开发板 Linux内核等待队列poll ---阻塞与非阻塞

    开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 阻塞:阻塞调用是指调用结果 ...

  3. Python error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat)解决方案

    error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat). Get it - 解决方案 python通过pi ...

  4. Technical

    CAN FD (CAN with Flexible Data-Rate) is an extension to the original CAN bus protocol specified in I ...

  5. java8_api_xml

    xml处理-1    解析xml的两种方式    DOM主要接口介绍    使用DOM解析XML        解析(parse)是指读入一个文件,确认其有正确的格式,然后将其分解成各种元素,使开发者 ...

  6. linux下目录简介——/proc

    1. /proc目录Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文 ...

  7. python selenium-webdriver 登录验证码的处理(十二)

    很多系统为了防止坏人,会增加各样形式的验证码,做测试最头痛的莫过于验证码的处理,验证码的处理一般分为三种方法 1.开发给我们设置一个万能的验证码: 2.开发将验证码给屏蔽掉: 3.自己识别图片的上的千 ...

  8. java-使用icepdf实现pdf转换成png

    下载icepdf的架包,并导入项目中,这里用到4个,如下: /** * 本地pdf文件转png */ public static int pdf2pngByFile(String target){ S ...

  9. python 将本地目录暴露为http服务

    python3 nohup python3 -m http.server 8080 &

  10. vue插件大全汇总

    Vue是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件特别整理了常用的vue插件,来了个大汇总,方便查找使用,便于工作 ...