zoukankan      html  css  js  c++  java
  • 浅谈synchronized

    浅谈synchronized

    前言

    看多线程的相关书籍的时候,会经常阅读到一个使用前景,就是银行的取钱存钱操作。
    假设我们使用两个线程来模拟取钱操作,模拟两个人使用同一个账户并发取钱的问题,我们都知道存款不可能为负的,
    但是往往并发操作的时候,可能就会导致系统出错导致出现负的数字(假设一开始都是200元余额,两边同时操作取出150,系统可能就会出错)。
    出现类似这种问题就是缺少同步安全性,为了解决这个问题,Java就增进了同步监视器来解决这个,也就是本文讲的synchronized的作用。

    是什么

    synchronized是Java中的关键字。同步的意思,用在解决线程安全问题上。有添加在方法上,和直接修饰代码块。有种保护的作用,使用修饰之后,家门上了锁,别人进不来。用synchronized修饰的方法只允许一个线程执行,其他线程无法进入该方法。(原子性操作),银行使用该操作之后,就会变成一个排队操作一样,像前言的例子,就会变成一个人等另一个操作取出150之后才可以取钱,这样就不会出现负的余额。

    1. 基本上所有的并发模式 在解决线程冲突的时候,都是采用序列化访问共享资源的方案。就是在给定的时间间隔内只允许一个任务访问共享资源。
    所以synchronized保护的是线程遭受破坏,必须按照允许的权限进行资源访问。
    

    记得synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造函数、属性等。

    //long与double的操作不是原子的
    

    格式

    同步代码块

    //synchronized代码块
    //obj对象即表示线程开始执行同步代码块之前,必须先获得对同步监视器的锁定
    //步骤:加锁--修改--释放锁
    synchronized (obj) {
        ...
    }
    
    

    任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。具体的格式参见上面。

    同步方法

    //synchronized方法,可以分为静态方法和普通方法
    synchronized void method(){
        ...
    }
    //等价于
    public void method()
    {
       synchronized(this) {
          // todo
       }
    }
    //无论哪种形式都可以看做是“{”处获取锁,“}”释放锁
    

    与同步代码块对应,Java 的多线程安全支持还提供了同步方法,同步方法就是使用synchronized关键字来修饰某个方法(放在权限词的后面即可),则该方法称为同步方法。对于同步方法而言,无须显式指定同步监视器,同步方法的同步监视器是this,也就是该对象本身。在格式上可以看到一些用法,但是具体来讲,synchronized用在方法体上还分为用在普通方法和静态方法两种,区别在作用锁对象的不同。

    修饰普通方法作用的是调用这个方法的对象,修饰静态方法作用是调用这个类的所有对象。
    synchronized static方法可以在类的范围内防止对static数据的并发访问,
    

    使用同步方法可以很方便得实现线程安全的类,这样类的对象可以被多个线程同时安全得访问。

    注意

    1. synchronized不能被继承。
    2. collection中的线程不安全的集合可以变成使用Collections工具类的,具体用法语句可以参考API文档,写的还算比较详细。

    最后

    1. 关于什么使用同步,也就是上锁,引用书上的话

      如果你在写一个变量,它可能接下来将被另一个线程读取,或者正在读取上一个已经被另一个线程写过的变量,那么你必须使用同步,并且,读取线程都必须用相同的监视器锁同步

      ​ ——Brain Goetz《Java Concurrency in Pactice》的作者

    2. 个人学习记录,有错误欢迎指点,谢谢!加油!

  • 相关阅读:
    数组的学习(一)
    Servlet是线程安全吗?
    MySql用户管理:添加用户、授权、删除用户
    泛型(二)
    泛型(一)
    Spring MVC
    spring框架
    mybatis基础
    Hibernate 基础
    Java局部类
  • 原文地址:https://www.cnblogs.com/yhycoder/p/12267191.html
Copyright © 2011-2022 走看看