Java并发编程入门(一)

一、为什么要并发?

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

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的情况。

原文地址:https://www.cnblogs.com/ygria/p/9315633.html

时间: 2024-12-11 09:38:30

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

Java并发编程入门与高并发面试

第1章 课程准备(入门课程)课程目标:Java并发编程入门,适合没有并发编程经验的同学,本章首先从课程重点.特点.适合人群及学习收获几个方面对课程进行整体的介绍,然后会从一个实际的计数场景实现开始,给大家展示多线程并发时的线程不安全问题,让大家能够初体验到并发编程,之后会讲解并发和高并发的概念,并通过对比让大家明白到底什么是并发和...1-1 课前必读(不看会错过一个亿)1-2 课程导学1-3 并发编程初体验1-4 并发与高并发基本概念(选看)1-5 JAVA内存模型1-6 并发的优势与风险(选

Java并发编程入门(二)

1.竞态条件 1.1 定义 当某个计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件.换句话说,正确的结果要取决于运气. 最常见的竞态条件类型:先检查后执行(Check-Then-Act)操作,即通过一个可能失效的观测结果来决定下一步的动作. 1.2 特征 与大多数并发错误一样,竞态条件并不总是会产生错误,还需要某种不恰当的执行时序. 1.3 复合操作 为了确保线程安全性,"先检查后执行"(例如延迟初始化)和"读取-修改-写入"等操作统称为复合操作:包含了

Java学习笔记—第十二章 Java网络编程入门

第十二章  Java网络编程入门 Java提供的三大类网络功能: (1)URL和URLConnection:三大类中最高级的一种,通过URL网络资源表达方式,可以很容易确定网络上数据的位置.利用URL的表示和建立,Java程序可以直接读入网络上所放的数据,或把自己的数据传送到网络的另一端. (2)Socket:又称"套接字",用于描述IP地址和端口(在Internet中,网络中的每台主机都有一个唯一的IP地址,而每台主机又通过提供多个不同端口来提供多种服务).在客户/服务器网络中,当客

Java并发编程原理与实战视频教程

14套java精品高级架构课,缓存架构,深入Jvm虚拟机,全文检索Elasticsearch,Dubbo分布式Restful 服务,并发原理编程,SpringBoot,SpringCloud,RocketMQ中间件,Mysql分布式集群,服务架构,运 维架构视频教程 14套精品课程介绍: 1.14套精 品是最新整理的课程,都是当下最火的技术,最火的课程,也是全网课程的精品: 2.14套资 源包含:全套完整高清视频.完整源码.配套文档: 3.知识也 是需要投资的,有投入才会有产出(保证投入产出比是

《Java并发编程之美》(翟陆续著)高清pdf

<Java并发编程之美> 阿里巴巴技术专家力作,用代码说话.用实例验证,并发编程没有这么难!<Java并发编程的艺术>*作者方腾飞老师好评推荐! ? 百度网盘链接: https://pan.baidu.com/s/12oEEeDEO_YofImkpQA1bLA 提取码: pmkh  内容简介  · · · · · · 并发编程相比 Java 中其他知识点的学习门槛较高,从而导致很多人望而却步.但无论是职场面试,还是高并发/ 高流量系统的实现,却都离不开并发编程,于是能够真正掌握并发

Java并发编程:Concurrent锁机制解析

.title { text-align: center } .todo { font-family: monospace; color: red } .done { color: green } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal } .timestamp { color: #bebebe } .timestamp-kwd

Java并发编程:Callable、Future和FutureTask(转)

Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果. 今天我们就来讨论一下Callabl

Java并发编程 Volatile关键字解析

volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的. 2)禁止进行指令重排序. 根据volatile的语义,我们可以看到,volatile主要针对的是并发三要素(原子性,可见性和有序性)中的后两者有实际优化作用. 可见性: 线程本身并不直接与主内存进行数据的交互,而是通过线程的工作内存来完成相应的操作.

Java并发编程

synchronized是Java中的关键字,在并发编程中被称为内置锁或者监视器锁.当用它来修饰一个方法或者一个代码块的时候能够保证同一时刻最多只有一个线程执行该段代码. Java的内置锁相当于一种互斥锁,最多只有一个线程能够持有这种锁,故而由这个锁保护的同步代码块会以原子方式执行,多个线程在执行该代码时就不会相互干扰. 但由于被锁保护的同步块代码是以串行形式来访问的,即多个线程以独占的方式访问对象,而这也导致如果被锁保护的同步代码块的作用范围过大,会导致并发不良. 这里有必要简单讲一下内置锁的