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

    为什么要用synchronized关键字:

      synchronized是java的一种内部锁,是一种排他锁,通常也被称为悲观锁,它能够保障原子性,可见性,有序性。

      当多个线程去调用同一个方法的时候,如果不用加synchronized锁,就可能出现线程不安全的问题。举个经典的例子,比如两夫妻一个用银行卡,一个用网银同时取同一个账户的钱,

    取钱这个操作在银行的后台肯定是一个方法,如果两方同时调用,很有可能造成取了两份的钱,这样肯定是不行的。

    synchronized的两种使用方式:

      1,synchronized加在方法上

    public class T {
    
        private int count = 10;
        
        public synchronized void m() {
            count--;
            System.out.println(Thread.currentThread().getName() + " count = " + count);
        }
    
    }

      2,synchronized代码块

    public class T {
    
        private int count = 10;
    
        public void m() {
            synchronized(this) {
                count--;
                System.out.println(Thread.currentThread().getName() + " count = " + count);
            }
        }
    
    }

    这里两种方式达到的效果是一样的,我们需要关注以下几点:

      1,synchronized锁,锁的是什么东西。其实是锁的一个对象,任意对象都可以(String常量,Integer,Long不能使用)。当一个线程拿到锁之后,其他的线程就只能等待当前线程执行完,

    并释放锁之后,才能拿到锁并执行。以此来保证线程的安全。

      2,这两种方式我们该用哪一种呢?实际开发中,我们应该用代码块的方式,为什么要加锁,通常都是需要访问共享变量才会加锁,一个方法中并不是所有代码都需要访问共享变量,

    其他的业务逻辑是不需要加锁的,所以代码块的方式可以提高程序的性能。

      3,synchronized是一种可重入的锁,什么意思呢,就是如果synchronized代码块中又调用了另外一个加锁的方法,本来如果锁没有释放,是不能拿到锁的。但是可重入锁是可以的,系统会自动识别。

    synchronized的底层实现:

      jdk早期的时候,synchronized的底层实现是重量级的,重量到可能需要到操作系统去申请锁的地步,所以造成synchronized的效率非常低。jdk1.6之后进行了改进,有了锁升级的概念。

    当我们访问synchronized的时候,HotSpot的实现是这样的,当第一个线程来访问的时候,先在锁对象的头上markword记录这个线程,实际上只要一个线程来访问的时候,是不会加锁的,

    只是记录这个线程ID,此时称之为偏向锁

      偏向锁如果有线程竞争的话,比如我第一个线程还没有释放锁,第二个线程又来了,就会自动升级为自旋锁,自旋锁的实现原理就是,线程会一直转圈等待获取锁,如果转圈十次之后,还没有获取到锁

    就自动升级为重量级锁

      所以说从效率方面来讲,CAS(后续文章会讲解)并不是一定就比synchronized锁的效率高,理解synchronized的底层实现,我们就可以得到如下结论:

    • 被锁住的代码,执行实际短,线程数量少的情况,用CAS。
    • 被锁住的代码,执行时间长,线程数量多的情况,用系统锁(synchronized内部锁和lock显示锁)。

      为什么这样说呢,假如我有1000个线程,用CAS自旋,那岂不是有999个线程会一直在旋转等待,这样是非常消耗资源的。

  • 相关阅读:
    AngularJS Insert Update Delete Using PHP MySQL
    Simple task manager application using AngularJS PHP MySQL
    AngularJS MySQL and Bootstrap Shopping List Tutorial
    Starting out with Node.js and AngularJS
    AngularJS CRUD Example with PHP, MySQL and Material Design
    How to install KVM on Fedora 22
    Fake_AP模式下的Easy-Creds浅析
    河南公务员写古文辞职信
    AI
    政协委员:最大愿望是让小学生步行上学
  • 原文地址:https://www.cnblogs.com/liu-yi/p/12945137.html
Copyright © 2011-2022 走看看