码迷,mamicode.com
首页 > 其他好文 > 详细

synchronized的用法

时间:2019-05-29 23:41:22      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:必须   for   访问   sys   为什么   href   www   没有   指令   

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

1. synchronized关键字

1. 介绍

synchronized关键字是java提供的锁机制, 主要解决线程同步的问题, 那么它可以修饰方法和同步代码块, 锁使用的范围一般情况是越小越好

2. 原理

synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的. 但是监视器锁本质又是依赖于底层的操作系统的互斥锁(Mutex Lock)来是实现的. 而操作系统实现线程之间的切换这就需要从用户态转换到核心态, 这个成本非常高, 状态之间的转换需要相对比较长的时间, 这就是为什么synchronized效率低的原因. 这种依赖于操作系统互斥锁锁是吸纳的锁, 我们称之为重量级锁

3. synchronized的两种用法

public class ATest {

    // 作用在方法上的synchronized关键字
    public synchronized void method1() {
        for (int i = 0; i < 100; i++) {
            System.out.println(i);
        }
    }
    // 作用在代码块的synchronized关键字
    public void method2() {
        synchronized (this) {
            for (int i = 0; i < 100; i++) {
                System.out.println(i);
            }
        }
    }
}

4. 单例模式

public class Singleton {

??private static Singleton instance = null;

??private Singleton() { }

??public static Singleton getInstance() {

?????if(instance == null) {

????????synchronzied(Singleton.class) {

???????????if(instance == null) {

???????????????instance = new Singleton();??//非原子操作

???????????}

????????}

?????}

?????return instance;

???}

}

2. volatile关键字

参考: https://www.cnblogs.com/dolphin0520/p/3920373.html

正确使用 volatile 变量的条件

您只能在有限的一些情形下使用 volatile 变量替代锁。要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:

  • 对变量的写操作不依赖于当前值。
  • 该变量没有包含在具有其他变量的不变式中。

实际上,这些条件表明,可以被写入 volatile 变量的这些有效值独立于任何程序的状态,包括变量的当前状态。

第一个条件的限制使 volatile 变量不能用作线程安全计数器。虽然增量操作(x++)看上去类似一个单独操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,必须以原子方式执行,而 volatile 不能提供必须的原子特性。实现正确的操作需要使 x 的值在操作期间保持不变,而 volatile 变量无法实现这点。(然而,如果将值调整为只从单个线程写入,那么可以忽略第一个条件。)

3. synchronized和volatile的区别

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是
立即可见的。
2)禁止进行指令重排序。
volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;
synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。

1.volatile仅能使用在变量级别;
synchronized则可以使用在变量、方法、和类级别的

2.volatile仅能实现变量的修改可见性,并不能保证原子性;

synchronized则可以保证变量的修改可见性和原子性

3.volatile不会造成线程的阻塞;
synchronized可能会造成线程的阻塞。

4.volatile标记的变量不会被编译器优化;
synchronized标记的变量可以被编译器优化

synchronized的用法

标签:必须   for   访问   sys   为什么   href   www   没有   指令   

原文地址:https://www.cnblogs.com/lingshang/p/10946955.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!