一、为什么要并发?

出现背景:操作系统的出现,使计算机同时运行多个程序成为可能。

1、目的:

资源利用率。某些时候,程序必须等待一些外部操作完成(IO)才能继续运行,在等待时间运行其他程序,可以有效提高资源利用率。

公平性。不同的用户和程序对计算机的资源有公平的利用率。

便利性。为了完成一个任务,同时运行多个计算机程序并进行通信,比只运行一个计算机程序更方便。

2、线程

线程也被称为轻量级进程,如果没有调度机制,线程将独立运行。同一进程中的所有线程共享进程的地址空间,实现了更细粒度的资源共享机制。

优势:降低程序的开发与维护成本,提升复杂应用程序的性能。线程能将大部分异步工作流转化成串行工作流,能更好地模拟人类工作和交互方式,并提高机器的资源利用率和吞吐量。

执行同一类型任务的优势:减少切换成本,程序更容易编写和测试,减少错误率。

风险:

安全性:在没有充足同步的情况下,多个线程的执行顺序是不可预测的,甚至会产生奇怪的后果。

活跃性:潜在的阻塞问题。

性能:引入多线程后,线程调度带来的额外开销。

二、线程安全

1、核心:对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问。

“共享”意味着变量可以由多个线程同时访问,而“可变”则意味着变量的值可以在其生命周期内发生变化。一个对象是否线程安全,取决于它是否被多个线程访问,若要实现线程安全,需要采用同步机制来协同对对象可变状态的访问,如果无法实现协同,那么可能会导致数据破坏以及其他不该出现的结果。

Java同步机制:

关键字:synchronized

提供了一种独占的加锁方式。

2、定义:正确性

含义:某个类的行为与其规范完全一致。在良好的规范中,通常会定义各种不变性条件来约束的对象的状态,以及定义各种后验条件来描述对象操作的结果——代码可信性。

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

示例1:线程安全的Servlet

@ThreadSafe
public class StatelessFactorizer implements Servlet{
  public void service( ServletRequest req, ServletResponse resp){
      BigInteger i = extractFromRequest( req);
      BigInteger[] factors = factor( i);
      encodeIntoResponse( resp, factors);
  }
}

无状态的Servlet是线程安全的。

大多数的Servlet都是无状态的,从而极大地降低了实现Servlet线程安全时的复杂性问题。只有当Servlet处理请求时需要保存信息时,线程安全才会成为问题。

3、原子性

示例2:非线程安全的Servlet

@NotThreadSafe
public class UnsafeCountingFactorizer implements Servlet {
    private long count = 0;
    public long getCount(){
        return count;
    }

    public void service(ServletRequest req, ServletResponse resp){
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = factor(i);
    }
}

导致线程不安全的原因:count++并非一个原子性的操作,它包含三步操作:读取-写入-修改。如果两个线程同时读取值为9,并分别执行增加操作,则会导致最终值偏差1的情况。

Java并发编程入门(一)的更多相关文章

  1. Java并发编程入门与高并发面试(三):线程安全性-原子性-CAS(CAS的ABA问题)

    摘要:本文介绍线程的安全性,原子性,java.lang.Number包下的类与CAS操作,synchronized锁,和原子性操作各方法间的对比. 线程安全性 线程安全? 线程安全性? 原子性 Ato ...

  2. Java并发编程入门,看这一篇就够了

    Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容.这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉 ...

  3. Java并发编程入门(二)

    1.竞态条件 1.1 定义 当某个计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件.换句话说,正确的结果要取决于运气. 最常见的竞态条件类型:先检查后执行(Check-Then-Act)操 ...

  4. Java并发编程实战3-可见性与volatile关键字

    1. 缓存一致性问题 在计算机中,每条指令都是在CPU执行的,而CPU又不具备存储数据的功能,因此数据都是存储在主存(即内存)和外存(硬盘)中.但是,主存中数据的存取速度高于外存中数据的存取速度(这也 ...

  5. Java 并发编程-不懂原理多吃亏(送书福利)

    作者 | 加多 关注阿里巴巴云原生公众号,后台回复关键字"并发",即可参与送书抽奖!** 导读:并发编程与 Java 中其他知识点相比较而言学习门槛较高,从而导致很多人望而却步.但 ...

  6. Java工程师学习指南第4部分:Java并发编程指南

    本文整理了微信公众号[Java技术江湖]发表和转载过的Java并发编程相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧吧. [纯干货]Java 并发进阶常见面试题总结 [Java基本功] ...

  7. 如何深入学习Java并发编程?

    在讲解深入学习Java并发编程的方法之前,先分析如下若干错误的观点和学习方法. 错误观点1:学习Java编程主要是学习多线程. 这话其实是说明了表面现象,多线程其实还真是并发编程的实现方式,但在实际高 ...

  8. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  9. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

随机推荐

  1. SQL计算算数表达式的函数自定义(加减乘除)

    一.整体思路:循环遍历表达式字符串,设置一个index从第一个字符开始检测当前数字是否可以和后面的数字进行运算,如果可以运算,将两个数挑出来运算,然后用运算的结果替换原来表达式中的这两个数和符号,计算 ...

  2. 01-Vue初学习

    1. Vue下载 (1)网址:https://cn.vuejs.org/v2/guide/installation.html (2)点击开发版本,下载完成是一个 Vue.js 2. 使用 (1)创建文 ...

  3. mac OS 安装 Subversion JavaHL 客户端

    JavaHL原来官网  http://subclipse.tigris.org/wiki/JavaHL 目前已经全部转移到github 官方说明很详细 https://github.com/subcl ...

  4. BeanDefinition源码解析

    我们知道BeanDefintion定义了Bean在IoC容器内的基本数据结构.在学习IoC之前先了解BeanDefition对我们理解IoC容器是有帮助的. 首先BeanDefinition是一个接口 ...

  5. STL学习心得

    STL的知识翻来复去,也就那么回事,但是真的想要熟练使用,要下一番功夫.无论是算法,还是STL容器,直白的说就是套路,然而对于一道题,告诉你是STL容器的题,让你套容器也绝非易事. 怎样使用容器,对于 ...

  6. 日常开发中常用的linux命令

    本文并不将linux的常用命令全部罗列出来,列出一下常用.容易忘记的命令. 更详细的说明见:https://www.cnblogs.com/xuxinstyle/p/9609551.html 文件相关 ...

  7. django项目的uwsgi方式启停脚本

    #!/bin/sh NAME="fushentang" if [ ! -n "$NAME" ];then echo "no arguments&quo ...

  8. win7 64位系统使用vs2010编译OSG3.2.1

    首先我想说的是,osg是有二进制安装包的:http://openscenegraph.alphapixel.com/osg/downloads/free-openscenegraph-binary-d ...

  9. Redis超详细总结

    NoSQL概述 一.数据存储的演化史 1.单机MySQL的美好年代 在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付.在那个时候,更多的都是静态网页,动态交互类型的网站不多. 上述 ...

  10. 抓住CoAP协议的“心”

    摘要 The Constrained Application Protocol(CoAP)是一种专用的Web传输协议,用于受约束的节点和受约束的(例如,低功率,有损)网络. 节点通常具有带少量ROM和 ...