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. LEB128相关知识

    LEB128相关知识 介绍 LEB128(little endian base 128)是一种变长的整数压缩编码形式,它是出自于DWARF debug file format.在Android的Dal ...

  2. webbrowser 里的js函数和C#的函数互相调用方式

    1.c#程序里要添加  [System.Runtime.InteropServices.ComVisibleAttribute(true)] 和  webBrowser1.ObjectForScrip ...

  3. spring事务详解(一)初探事务

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 引子 很多 ...

  4. 详解java定时任务---Timer篇

    一.简介      在java的jdk中提供了Timer.TimerTask两个类来做定时任务. Timer是一种定时器工具,用来在一个后台线程计划执行指定任务,而TimerTask一个抽象类,它的子 ...

  5. 使用velodyne16线激光雷达跑loam-velodyne

    一.velodyne-VLP16使用教程 推荐网址: http://blog.csdn.net/littlethunder/article/details/51920681 https://www.c ...

  6. lnmp一件安装包 搭建laravel 环境(lnmp1.4)(报错500)

    https://blog.csdn.net/huangyuxin_/article/details/78998486

  7. VirtualApk 插件入门小试

    1 官方资料 滴滴开源Android插件方案:VirtualAPK 2 宿主App集成方法 (1)在整个工程的build.gradle中添加依赖 dependencies { classpath 'c ...

  8. JavaScript 环境和作用域

    作用域 1. 全局环境 window: JS的全局执行环境,顶层对象.this指针在全局执行环境时就指向window. console.log(this===window); //true 2. 局部 ...

  9. 【java】之算法复杂度o(1), o(n), o(logn), o(nlogn)

    在描述算法复杂度时,经常用到o(1), o(n), o(logn), o(nlogn)来表示对应算法的时间复杂度, 这里进行归纳一下它们代表的含义: 这是算法的时空复杂度的表示.不仅仅用于表示时间复杂 ...

  10. windows下的端口转发命令netsh

    使用下面的命令查看语法 netsh interface portproxy add v4tov4 /? add v4tov4 [listenport=]<integer>|<serv ...