zoukankan      html  css  js  c++  java
  • 线程安全性的基础知识

      “共享”意味着变量可以由多个线程同时访问,而“可变”则意味着变量的值在其周期内是可以发生变化的。

      一个对象是否是线程安全的,取决于它是否被多个线程访问。

      当多个线程的访问某个状态变量并且其中某一个线程执行写操作时,必须采用同步机制来协同这些线程对变量的访问。java的同步机制是关键字synchronized,提供了一个独占的加锁方式。

      当多个线程访问同一个可变的状态变量时,可以使用以下三种方式避免错误:

      1、不在线程之间共享该变量状态。

      2、将该变量状态修改为不可变的变量。

      3、在访问变量中使用同步机制。

      线程安全性:某个类的行为与其规范完全一致。在良好的规范中通常会定义各种不变性条件(Invariant)来约束对象的状态,以及定义各种后验条件(Postcondition)来描述对象的操作结果。

      线程安全的类: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程如何的交替运行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。无状态对象一定是线程安全的,大多数servlet都是无状态的。

      竞态条件: 多个线程执行时序不同而导致不同的结果。

      复合操作:多个原子操作组合在一起的操作称为复合操作。只有在复合操作中出现竞态条件问题。

    1、内置锁,

      Java提供了一种内置的锁机制来支持原子性:同步代码块(Synchronized  block),关键字为synchronized,用该关键字来修饰方法就是一种跨越整个方法的同步代码块。

      Java内置锁相当于一种互斥体(或互斥锁),就意味着最多只有一个线程持有这种锁。

    2、重入

      重入:某个线程试图获得一个已经由它本身自己持有的锁,那么这个请求就会 成功。重入意味着锁的操作粒度是“线程”,而不是"调用"。

      比如下面的代码块:

     1 public class People {
     2     public synchronized void doSomething(){
     3         System.out.println("doSomething");
     4     }
     5 }
     6 
     7 
     8 public class XiaoMing extends People {
     9     public synchronized void doSomething(){
    10         System.out.println("xiaoMing do something");
    11         super.doSomething();
    12     }
    13 }
    View Code

      如果内置锁是不可以重入的话,那么在条用子类的doSomething()时将无法获得父类的锁,因为这个锁已经被持有,从而线程就被永远停顿下去。重入则避免了这种情况的发生。

     

  • 相关阅读:
    【LintCode题集】Q539
    【LintCode题解】Q407
    【LintCode题集】Q6、Q64
    【Java安全】关于Java中常用加密/解密方法的实现
    【MySQL】MySQL5.7的安装与配置
    理解CSS3 max/min-content及fit-content等width值
    Django和MySQL数据库第一次连接时遇到的若干问题及解决办法
    使用Pycharm社区版启动Django的重要补充
    使用Pycharm社区版新建Python3.7的虚拟环境并安装启动Django的完整步骤
    04-图形化编辑器功能不全?
  • 原文地址:https://www.cnblogs.com/Hxinguan/p/7455860.html
Copyright © 2011-2022 走看看