zoukankan      html  css  js  c++  java
  • 线程安全问题synchronized锁

    1.线程安全问题的原因

    因为 Java 中对静态变量的自增,自减并不是原子操作,要彻底理解,必须从字节码来进行分析
    例如对于 i++ 而言(i 为静态变量),实际会产生如下的 JVM 字节码指令: 

     2.临界区 Critical Section

    一个程序运行多个线程本身是没有问题的
    问题出在多个线程访问共享资源
    多个线程读共享资源其实也没有问题
    在多个线程对共享资源读写操作时发生指令交错,就会出现问题
    一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区 
    3.synchronized 解决方案
    1.synchronized,来解决上述问题,即俗称的【对象锁】,它采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】,其它线程再想获取这个【对象锁】时就会阻塞住。这样就能保证拥有锁
    的线程可以安全的执行临界区内的代码,不用担心线程上下文切换
    为了加深理解,请思考下面的问题北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090
    如果把 synchronized(obj) 放在 for 循环的外面,如何理解?-- 原子性
    如果 t1 synchronized(obj1) 而 t2 synchronized(obj2) 会怎样运作?-- 必须是同一个锁对象
    如果 t1 synchronized(obj) 而 t2 没有加会怎么样?如何理解?-- 要加就全加
    2.synchronized 实际是用对象锁保证了临界区内代码的原子性,临界区内的代码对外是不可分割的,不会被线程切换所打断
    3.将加了.synchronized的代码块jvm指令作为一个整体
    4.synchronized锁,其他想要获取锁的线程阻塞,状态为bolocked
    5.方式
    class Test{
     public synchronized void test() {
     
     }
    }
    等价于
    class Test{
     public void test() {
     synchronized(this) {
     
     }
     }
    }
    
    class Test{
     public synchronized static void test() {
     }
    }
    等价于
    class Test{
     public static void test() {
     synchronized(Test.class) {
     
     }
     }
    }
    
    6. private 或 fifinal 提供【安全】的意义所在,请体会开闭原则中的【闭】 ,不让子类影响父类方法,防止子类复写方法,里面创建另一个线程来修改传进来变量
    7.常见线程安全类
    String
    Integer
    StringBuffffer
    Random
    Vector
    Hashtable
    java.util.concurrent 包下的类
    (1)这里说它们是线程安全的是指,多个线程调用它们同一个实例的某个方法时,是线程安全的。也可以理解为
    (2)它们的每个方法是原子的
    (3)但注意它们多个方法的组合不是原子的,见后面分析 
    8.String类为啥用final修饰呢
    防止子类继承,覆写方法,导致线程不安全
    9.private 修饰的方法与成员变量
     
      
     
     
  • 相关阅读:
    Windows 8 C#调用C++编写的Windows运行时组件
    Metro style App Datetime formating.
    《编程匠艺》读书笔记之一
    ContextMenu的使用
    单例模式
    c# 类中字段属性设计
    Metro style app 文件查找
    Win 8 学习资料汇总
    Metro C++ 初体验 第二周
    Metro style app 文件、文件夹的选择、文件的保存。
  • 原文地址:https://www.cnblogs.com/hejunhong/p/12562365.html
Copyright © 2011-2022 走看看