一:为什么需要多线程?

线程是Java语言中不可或缺的重要部分,它们能使复杂的异步代码变得简单,简化复杂系统的开发;能充分发挥多处理器系统的强大计算能力。多线程和多进程的区别与选择可以参考我的另一篇博客。

(1) 优点

1. 充分利用硬件资源。由于线程是cpu的基本调度单位,所以如果是单线程,那么最多只能同时在一个处理器上运行,意味着其他的CPU资源都将被浪费。而多线程可以同时在多个处理器上运行,只要各个线程间的通信设计正确,那么多线程将能充分利用处理器的资源。

2. 结构优雅。多线程程序能将代码量巨大,复杂的程序分成一个个简单的功能模块,每块实现复杂程序的一部分单一功能,这将会使得程序的建模,测试更加方便,结构更加清晰,更加优雅。

3. 简化异步处理。为了避免阻塞,单线程应用程序必须使用非阻塞I/O,这样的I/O复杂性远远高于同步I/O,并且容易出错。

(2) 缺点

1. 线程安全:由于统一进程下的多个线程是共享同样的地址空间和数据的,又由于线程执行顺序的不可预知性,一个线程可能会修改其他线程正在使用的变量,这一方面是给数据共享带来了便利;另一方面,如果处理不当,会产生脏读,幻读等问题,好在Java提供了一系列的同步机制来帮助解决这一问题,例如内置锁。

2. 活跃性问题。可能会发生长时间的等待锁,甚至是死锁。

3. 性能问题。 线程的频繁调度切换会浪费资源,同步机制会导致内存缓冲区的数据无效,以及增加同步流量。

二:线程安全

(1) 定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替运行,并且在主调试代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,则称这个类时线程安全的。线程安全类中封装了必要的同步机制,因此客户端无须进一步采取同步措施。

(2) 线程安全产生的原因:正确性取决于多个线程的交替执行时序,产生了竞态条件。

(3) 原子类: 应尽量使用原子类,这样会让你分析线程安全时更加方便,但需要注意的是用线程安全类构建的类并不能保证线程安全。例如,一个AtomicInteger get() 和 AtomicInteger set() 是线程安全的,在一个类的一个方法 f()中同时用到了这两个方法,此时的f()就是线程不安全的,因为你不能保证这个复合操作中的get 和 set同时更新。

三:解决机制

1. 加锁。

(1) 锁能使其保护的代码以串行的形式来访问,当给一个复合操作加锁后,能使其成为原子操作。一种错误的思想是只要对写数据的方法加锁,其实这是错的,对数据进行操作的所有方法都需加锁,不管是读还是写。

(2) 加锁时需要考虑性能问题,不能总是一味地给整个方法加锁synchronized就了事了,应该将方法中不影响共享状态且执行时间比较长的代码分离出去。

(3) 加锁的含义不仅仅局限于互斥,还包括可见性。为了确保所有线程都能看见最新值,读操作和写操作必须使用同样的锁对象。

2. 不共享状态

(1) 无状态对象: 无状态对象一定是线程安全的,因为不会影响到其他线程。

(2) 线程关闭: 仅在单线程环境下使用。

3. 不可变对象

可以使用final修饰的对象保证线程安全,由于final修饰的引用型变量(除String外)不可变是指引用不可变,但其指向的对象是可变的,所以此类必须安全发布,也即不能对外提供可以修改final对象的接口。

Java 并发理论简述的更多相关文章

  1. Java并发理论简介

    这些文字来自于Java程序员修炼之道,记录一下 一. java线程模型 Java线程模型建立在两个基本概念之上 共享的,默认可见的可变状态 抢占式线程调度 我们从侧面思考一下这两个概念 所有线程可以很 ...

  2. JAVA并发理论与实践

    JDK5.0中更灵活.更具可伸缩性的锁定机制 流行的原子 非阻塞算法简介

  3. [Java并发编程(四)] Java volatile 的理论实践

    [Java并发编程(四)] Java volatile 的理论实践 摘要 Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 ...

  4. 【转】Java 并发编程:核心理论

    并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密,这样才能写出高效.安全.可靠的多线程并发程序.本系 ...

  5. (转)Java并发编程:核心理论

    原文链接:https://www.cnblogs.com/paddix/p/5374810.html Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及 ...

  6. Java 并发编程:核心理论(一)

    前言......... 并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密,这样才能写出高效.安全.可 ...

  7. Java 并发基础

    Java 并发基础 标签 : Java基础 线程简述 线程是进程的执行部分,用来完成一定的任务; 线程拥有自己的堆栈,程序计数器和自己的局部变量,但不拥有系统资源, 他与其他线程共享父进程的共享资源及 ...

  8. 【Java并发编程实战】-----“J.U.C”:Semaphore

    信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...

  9. java 并发性和多线程 -- 读感 (一 线程的基本概念部分)

    1.目录略览      线程的基本概念:介绍线程的优点,代价,并发编程的模型.如何创建运行java 线程.      线程间通讯的机制:竞态条件与临界区,线程安全和共享资源与不可变性.java内存模型 ...

随机推荐

  1. java 多级图的最短路径

    求最短路径众所周知有Dijistra算法.Bellman-ford等,除了这些算法,用动态规划也可以求出最短路径,时间复杂度为O(n^2), 跟没有优化的Dijistra算法一样(优化后的Dijist ...

  2. C#变量2

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 数据类型: (1).值类型 类型名称 CTS类型 说明 范围 ^ - ^-(--) ^-^-(-~) ^-^- ^-^- -(-^-) - ...

  3. 这 17 个 JVM 参数,高级 Java 必须掌握!

    作者:SimpleSmile https://www.cnblogs.com/Simple-Object/p/10272326.html前言 大家都知道,jvm在启动的时候,会执行默认的一些参数.一般 ...

  4. Spring Cloud注册中心高可用搭建

    Spring Cloud的注册中心可以由Eureka.Consul.Zookeeper.ETCD等来实现,这里推荐使用Spring Cloud Eureka来实现注册中心,它基于Netfilix的Eu ...

  5. [已解决]报错: Python Scrapy - service_identity(opentype) not working and cannot install

    解决:更新安装service_identity pip3 install service_identity --force --upgrade

  6. SQL语句的执行顺序和效率

    今天上午在开发的过程中,突然遇到一个问题,需要了解SQL语句的执行顺序才能继续,上网上查了一下相关的资料,现整理如下:一.sql语句的执行步骤: 1)语法分析,分析语句的语法是否符合规范,衡量语句中各 ...

  7. spark性能调优05-troubleshooting处理

    1.调节reduce端缓冲区大小避免OOM异常 1.1 为什么要调节reduce端缓冲区大小 对于map端不断产生的数据,reduce端会不断拉取一部分数据放入到缓冲区,进行聚合处理: 当map端数据 ...

  8. Linux解压rar文件

    Linux解压rar文件(unrar安装和使用,分卷解压) windows平台很多压缩文档为rar文件,那么怎么做到Linux解压rar文件(unrar安装和使用)? 简单,centos5安装unra ...

  9. KiCAD的一些快捷操作(类比于AD)

    一.原理图快捷操作 二.PCB快捷操作 Q: 在布线过程中,用来编辑线宽,和AD中布线时“Tab”的作用相似 W: 选择设定好的线宽,线宽减小 Shift+W: 选择设定好的线宽,线宽变大 /: 改变 ...

  10. 视频专家之路【二】:ffmpeg工具的使用

    本文是听了雷宵骅大神的课之后的总结,部分内容借用了其PPT的内容,如有侵权请告知删除. 雷宵骅大神的博客为:https://blog.csdn.net/leixiaohua1020 要学习汽修,那么首 ...