• Java多线程学习之synchronized总结


    0、概述

      synchronized是Java提供的内置的锁机制,来实现代对码块的同步访问,称为内置锁(Intrinsic Lock) 。内置锁包括两部分:一个是作为锁的对象的引用,另一个是由这个锁保护的代码块。需要理解的是,synchronized的锁都是对象的引用,同一个对象只有一个内置锁,不同的对象有不同的内置锁。

      Java 的内置锁是一种互斥锁,即一个对象的锁只能同时被一个线程持有。假设线程A尝试获取线程B持有的锁,线程A会被阻塞,知道B释放该锁,A才能持有该锁。如果线程B永远不是释放该锁,线程A也将永远等待下去,形成死锁。 由于线程在等待内置锁的过程中无法被中断,这是synchronized内置锁的一个弊端,该需求可以被显示锁ReentranLock解决,可以参考这篇博客:http://www.cnblogs.com/moongeek/p/7857794.html

      获得一个对象内置锁的唯一途径就是进入由该对象锁保护的代码块,释放锁的唯一途径是跳出该代码块。一般synchronized使用方法如下:

    synchronized(lock){
        // 访问或修改由该锁保护的共享状态
    }

    1、synchronized的使用

      synchronized可以修饰一般方法、static方法、代码块,但是不论synchronized修饰什么,他获取的都是一个对象的内置锁,锁的单位都是对象。

      1)synchronized 修饰一般方法,锁是持有该方法的对象的锁,访问同一个类的相同方法时候会互斥。

    public synchronized void doSomething(){     
        // ...
    }

    上代码等价于:

    public void doSomething(){ 
        synchronized(this){
              // ...
        }
    }

      2)synchronized 修饰代码块,锁是指定的对象的锁,如果是同一个对象的锁,那么会互斥访问。

    // 锁为object对象的锁
    synchronized(object){
      
    }

      3)synchronized 修饰静态方法,锁是该类Class对象的锁,该类的所有对象访问该类时都会互斥。

    public class Demo{
        public synchronized static void doSomething(){
            // ...
        }
    }

    上代码等价于:

    public class Demo{
        public static void doSomething(){
            synchronized(Demo.class){
                // ...
            }
        }
    }    

    2、可重入性

      当某个线程请求一个已经被其他线程持有的锁时,该线程会被阻塞。但是内置锁是可重入的,因此,如果一个内置锁尝试获得已经由他自己持有的锁,那这个请求会立即成功。“重入”意味着获取锁的操作粒度是“线程”而不是”调用“。

      重入的实现方法是,为每个所关联一个锁和一个计数值。当计数值为0时,这个锁就被认为是没有被任何线程持有。当线程请求一个未被持有的线程时,JVM记下这个持有者,并且将计数值增1.如果同一个线程再次获得这个锁,计数值将增加,而当线程退出同步代码块时,计数器相应的递减。当计数值为0,这个锁将被释放。

     1 public class Test {
     2     private Object  lock;
     3 
     4     public synchronized void saySomething(){
     5         
     6     }
     7 
     8     public synchronized void doSomething(){
     9         // 两个函数都是同一个对象锁,可重入
    10         saySomething();
    11     }
    12     
    13     public void goSomewhere(){
    14         // 对象锁不一致,不能重入
    15         synchronized (lock){
    16             saySomething();
    17         }
    18     }
    19 }
  • 相关阅读:
    PostgreSQL 遇到 column "value" does not exist
    FlowPortal BPM官网改版了,推出20个流程免费基础版
    C#代码规范化(代码风格化)的几个函数
    批量更新带有命名空间的XML文件的多个节点值
    旺财C# .NET代码生成器之DTcms4/5代码批量生成功能
    C# Webform中读取Windows AD/LDAP域用户清单
    在吉日嘎拉DotNet.WebForm中使用FluentScheduler调度任务
    修复一个吉日嘎拉MSSQL数据库版中的分页存储过程bug
    基于吉日嘎拉的OA协同办公模块重写
    基于吉日嘎拉的通用权限管理WebForm版扩展:字典选项管理和缓存管理
  • 原文地址:https://www.cnblogs.com/moongeek/p/7859089.html
Copyright © 2020-2023  润新知