java多线程编程01---------基本概念
一. java多线程编程基本概念--------基本概念
java多线程可以说是java基础中相对较难的部分,尤其是对于小白,次一系列文章的将会对多线程编程及其原理进行介绍,希望对正在多线程中碰壁的小伙伴有所帮助。
(一)进程、线程和任务
进程可以认为是程序执行的一个实例,是程序向操作系统申请资源的基本单位,每个进程都拥有自己独立的地址空间。
线程是操作系统能够进行运算调度的最小单元,它被包含在进程之中,一个进程可以有多个线程。同一个进程中的多个线程共享这个进程的资源。
每个线程完成的计算被称为任务。
(二)串行、并发和并行
串行:按照顺序完成多个任务。
并发:在一段时间内以交替的方式完成多个任务。
并行:以齐头并进的方式完成多个任务。
并发往往是带着部分串行的并发,并发的极致就是串行。一个处理器就可以实现并发,但并行需要多个处理器在同一个时刻各自运行一个线程来实现。
多线程编程的实质就是将任务的处理方式由串行改为并发。
(三)多线程编程的优缺点
- 优点
提高系统的吞吐率;调高响应性;充分利用多核处理器;最小化对资源的使用(相对于多进程)
- 缺点
可能会造成线程安全问题、线程活性问题、引起上下文切换
(四)竟态
竟态是指一个计算结果的正确性和时间有关的现象。竟态往往伴随着读脏数据问题(线程读到的是一个过时的数据)、丢失更新(一个线程对数据所做的更新没有体现到后续其他线程对该数据的读取上)。
竟态通常是在多个线程在没有采取任何控制措施的情况下并发更新、读取同一个共享变量。竟态的两种模式为:read-modify-write(读-改-写)和check-then-act(检测而后行动)。
(五)线程安全问题
线程安全问题概括起来变现为3个方面:原子性、可见性和有序性。
1. 原子性
原子性是指访问某个共享变量的操作从执行线程以外的其他线程来看,该线程要么执行结束,要么尚未发生,即其他线程不会看到该操作的中间结果。java语言中,任何数据类型的读操作都具有原子性,除了long和double类型的基本数据类型和引用数据类型的写操作都具有原子性。
Java中有两种方式实现原子性:使用锁、CAS
2. 可见性
可见性用于描述一个行程对共享变量的更新对于另外一个线程而言是否可见的问题。可见性的保障是通过使更新共享变量的处理器执行冲刷处理器缓存,使读取共享变量的处理器执行刷新处理器缓存。
父线程在启动子线程之前对共享变量的更新对于子线程来说是可见的,之后对于共享变量的更新对于子线称来说没有保障的。
3. 有序性
有序性用来描述一个线程的内存访问操作在另外一个线程看来是否有序的问题。
重排序可以分为一下三种:
1)编译器优化的重排序。编译器在保证貌似串行语义的情况下,可以重新安排语句的执行顺序。
2)指令级并行重排序:如果不存在数据依赖性,处理器可以语句对应机器指令的执行顺序。
3)内存系统重排序。由于处理器使用缓存和读写缓冲区,使得加载和存储操作看上去是乱序的。
(六)java内存模型和happens-before
Java内存模型使用happens-before关系来保证可见性和有序性。
1. java内存模型
java内存模型(即Java Memory Model,简称JMM)本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。由于JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),用于存储线程私有的数据,而Java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝的自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,工作内存中存储着主内存中的变量副本拷贝,前面说过,工作内存是每个线程的私有数据区域,因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成,其简要访问过程如下图

2. happens-before
happens-before有两层含义:
1)如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,第一个操作的执行顺序排在第二个操作之前。(这条是JMM对程序员的承诺)
2)两个操作之间存在happens-before关系,并不意味着java平台的具体实现必须要按照happens-before关系指定的顺序来执行,只要保证重排序之后的结果与按happens-before关系一致即可(这条JMM对编译器和处理器重排序的约束)。
貌似串行语义(as-if-serial)保证单线程内程序执行结果不改变,happens-before关系保证正确同步的多线程程序执行结果不改变。
具体规则:
- 程序顺序规则:同一个线程中的每个操作happens-before该线程中的任意后续操作。
- 内部锁规则:内部锁的释放happens-before后续每一个对该锁的申请
- volatile规则:对于一个volatile域的写happens-before后续每一个针对该变量的读操作
- 传递性:如果A happens-before B,B happens-before C,那么A happens-before C
- start()规则:如果线程执行操作B.start(),那么A线程中的B.start()操作happens-before B线程中的任意操作
- join()规则:如果A线程执行B.start()操作并成功返回,那么b线程中的任意操作happens-before A线程执行完B.start()返回后的任意操作。
- 程序中断规则:对线程iterrupted()的调用先行于被中断线程检测到中断事件的发生。
- 对象finalize规则:一个对象的初始化完成先行于它的finalize()方法的开始。
(七) 阻塞与非阻塞
阻塞和非阻塞用来形同多线程间的相互影响,一个线程占用了临界区资源,其他线程需要这个资源进行等待该资源的释放,会导致等待线程的挂起,这种情况就是阻塞,而非阻塞恰好相反,他强调没有一个线程可以阻塞其他线程,所有线程都会尝试着往前运行。
java多线程编程01---------基本概念的更多相关文章
- Java多线程编程总结一:多线程基本概念
Java多线程编程总结一 – 初识多线程 进程.多进程.线程.多线程的概念 进程(process):CPU的执行路径.通俗的说就是系统中正在运行的程序.比如我们打开了浏览器.QQ等等,这些程序一旦被打 ...
- Java多线程编程详解
转自:http://programming.iteye.com/blog/158568 线程的同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Ja ...
- Java多线程编程总结(精华)
Java多线程编程总结 2007-05-17 11:21:59 标签:多线程 java 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http ...
- Java多线程编程核心技术
Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...
- 《Java多线程编程核心技术》推荐
写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...
- Java多线程编程实战读书笔记(一)
多线程的基础概念本人在学习多线程的时候发现一本书——java多线程编程实战指南.整理了一下书中的概念制作成了思维导图的形式.按照书中的章节整理,并添加一些个人的理解.
- 《java多线程编程核心技术》(一)使用多线程
了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...
- Java多线程编程核心技术(二)对象及变量的并发访问
本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...
- Java - 32 Java 多线程编程
Java 多线程编程 Java给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特别 ...
随机推荐
- 洛谷 U10206 Cx的治疗
题目背景 「Cx的故事」众所周知,Cx是一个宇宙大犇.由于Cx在空中花园失足摔下,导致他那蕴含着无穷智慧的大脑受到了严重的损伤,许多的脑神经断裂.于是,Cx的wife(有么?)决定请巴比伦最好的医师治 ...
- Hystrix 断路器
断路器: 当客户端访问服务端,发现服务端有异常不能进行访问时,就会执行一个fallback 方法.
- libs/tools.js stringToDate dateToString 日期字符串转换函数
libs/tools.js stringToDate dateToString 日期字符串转换函数 import { stringToDate } from '@/libs/tools.js' e ...
- 使用Spring AOP切面解决数据库读写分离
http://blog.jobbole.com/103496/ 为了减轻数据库的压力,一般会使用数据库主从(master/slave)的方式,但是这种方式会给应用程序带来一定的麻烦,比如说,应用程序如 ...
- SQL 语句解决实际问题
在项目开发过程中,遇到数据库的查询问题 一.查询某表字段的信息 select * from syscolumns SELECT object_id('TB_KYChildProject') selec ...
- 抓取oracle数据库耗费资源的sql语句
oracle数据库连接业务系统,而有些sql语句的执行严重影响了oracle的性能,就如同mysql的慢查询一样,mysql可以开启慢查询日志定位这些造成数据库性能下降的语句,而oracle同样可以做 ...
- 35个Redis面试题
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库 ...
- 牛客OI赛制测试赛2 A 无序组数
链接:https://www.nowcoder.com/acm/contest/185/A来源:牛客网 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序 ...
- Mysql 锁总结
锁 部分总结参考博客 http://b.codejs.cc/articles/2017/10/23/1508749325215.html http://blog.csdn.net/cug_jiang1 ...
- 03 数据解析-Xpath
Xpath解析 XPath在Python的爬虫学习中,起着举足轻重的地位,对比正则表达式 re两者可以完成同样的工作,实现的功能也差不多,但XPath明显比re具有优势,在网页分析上使re退居二线. ...