一:为什么需要多线程?

线程是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. VTemplate模板引擎的使用--进阶篇

    1.<vt:template>与<vt:include>标签的不同 <vt:template>和<vt:include> 标签都包含file属性,如果这 ...

  2. 数学&计算机工程常用希腊字母表及其发音

  3. Linux应急响应基础

    文件排查 敏感目录文件分析 tmp目录 命令目录 /usr/bin /usr/sbin 开机启动项 /etc/init.d /etc/init.d是/etc/rc.d/init.d的软链接 文件时间 ...

  4. export的用法

    定义环境变量并且赋值 # export MYENV= //定义环境变量并赋值 # export -p declare -x HOME=“/root“ declare -x LANG=“zh_CN.UT ...

  5. grafana初体验

    1.centos版下载安装 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.4-1.x86_6 ...

  6. Python-装饰器的进阶 小知识点

    ⼀. 通⽤装饰器的回顾 开闭原则: 对增加功能开放. 对修改代码封闭 装饰器的作⽤: 在不改变原有代码的基础上给⼀个函数增加功能 通⽤装饰器的写法: def wrapper(fn): def inne ...

  7. 【目录】ASP.NET Core 基础教程

    ASP.NET Core 基础教程 ASP.NET Core 基础教程 ASP.NET Core 简介 ASP.NET Core Windows 环境配置 ASP.NET Core macOS 环境配 ...

  8. nginx匹配以XXX结尾的

    匹配以do结尾的所有文件:如http://192.168.126.168:8080/delivery/transportPlanData.do?startRelease=2019-07-06& ...

  9. sqlServer MERGE 对数据进行修改或插入自动视别 特别用于批量数据的插入或修改

    sqlServer MERGE   对数据进行修改或插入自动视别 特别用于批量数据的插入或修改    MERGE  customer AS targetTable   --目标表    USING ( ...

  10. android5.1 隐藏状态栏

    修改frameworks/base/core/res/res/values/dimens.xml文件中 <!-- Height of the status bar --> <!-- ...