一 ,多线程相关的一些概念

1,线程和进程:

线程指的是进程中一个单一顺序的控制流,

进程中可以并发多个线程,每条线程并行执行不同的任务,被认为是一个计算资源的集合。进程不能被任务是一个应用,因为有些应用有多个进程组成。

2,并行与并发:

并发:单核cpu运行多线程时,在一个时间段内,多个线程交叉运行,给人感觉是同时运行。

并行:多核cpu运行 多线程时,真正的在同一时刻运行。

所以如果是单核多线程并发执行,并不需要处理多线程的同步问题。

3,线程同步和线程安全:

线程同步: 多个并行执行的线程在同一时刻不会执行指定的程序段。

线程安全:在多线程并行运行环境下而不会引发数据错误。线程安全问题都是由“全局变量及静态变量”引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

区别:线程同步是解决线程安全的方法之一。

4,多线程的优点和缺点:

  1,有写耗时的任务放在后台运行,不用等待。

  2,一些等待的任务,比如用户输入,文件读取和网络收发数据,不用等待完成。

  3,整体效率更高

  缺点:线程切换消耗,线程的同步控制,更多的线程空间。

5,线程池技术:

线程池技术并不是实现线程同步,或者实现线程安全的技术。只是解决了大量线程的重建的消耗,池中保持一定数量的线程,即时开始处理任务。它是一种实现高并发的方案。比如说在Reactor多线程模型中使用了线程池技术。

6,JVM并发编程中的3个概念:

6.1,原子性

可认为时不可切分的操作,可以说一个指令,也可以有序的多个指令。要么完全执行成功,要么失败回退。

注意:一条Java语句,并不等同于一个原子性指令。

6.2,可见性

举例有三个线程并发,A , B , C线程, 访问同一个变量时,A线程修改了这个变量的值,B, C线程能够立即看得到修改的值。

6.3,有序性

程序执行的顺序按照代码的先后顺序执行。 JVM 内部对程序的有序性做了一些规范,能保证程序运行有序性。

但是存在指令重排的问题。一般来说,处理器为了提高程序运行效率,可能会对输入代码进行优化,最终会保证结果的一致性。

以上3个因素发生变化,都会影响到“线程同步”问题。以下同步解决方案中,都是为了解决这3个概念中的问题。

二,线程安全的技术方案

2.1 volatile变量技术:

作用于被操作的共享变量对象上。解决可见性问题。当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。而普通变量不能保证完全的可见性。

2.1.1作用:

  1,保证了可见性

  2,避免了JVM的指令重排序

缺点是volatile也无法保证对变量的任何操作都是原子性的。不能形成内存栅栏。

2.1.2  使用场景:

volatile关键字用于声明简单类型变量,如int、float、boolean等数据类型。如果这些简单数据类型声明为volatile,对它们的操作就会变成原子级别的。
原因是声明为volatile的简单变量,如果当前值由该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:

n = n + 1;
n++;

//作为标记状态量

volatile boolean flag = false;

 //线程1
while(!flag){ //默认情况执行
doSomething();
} //线程2
public void setFlag() { //线程2执行后,线程1停止
flag = true; //对于变量的操作时原子性的,不依赖于前值。
}

实现功能;实现了并发运行,以及对2个线程的切换。

1,   默认,线程1执行, 线程2未运行。

2,线程2运行, 线程1停止。

2.2  synchronized技术 (Java的线程同步技术之一)

在并发编程中,解决了原子性问题, 作用于多个线程的共同代码上。某个线程修改共享资源的时候,其他线程不能修改该资源,等待修改完毕同步之后,才能去抢夺CPU资源,完成对应的操作,保证了数据的同步性,解决了线程不安全的现象。

  Synchronized 是一种独占锁。在修饰静态方法时,锁的是类对象,如 Object.class。修饰非静态方法时,锁的是对象,即 this。修饰方法块时,锁的是括号里的对象。 每个对象有一个锁和一个等待队列,锁只能被一个线程持有,其他需要锁的线程需要阻塞等待。锁被释放后,对象会从队列中取出一个并唤醒,唤醒哪个线程是不确定的,不保证公平性。
  synchronized 锁住的是对象而非代码,只要访问的是同一个对象的 synchronized 方法,即使是不同的代码,也会被同步顺序访问。举例, A类内有 2个synchronized方法, 比如 add()  subtract()  且都是非static方法,2个并发线程分别访问这2个方法,即使执行不同的代码段,也依然被同步执行。因为这2个方法对应了同一个对象锁。 如果其中add() 方法为static方法,则可以并发执行,不需要同步。
 
  synchronized方法不能防止非synchronized方法被同时执行,所以,一般在保护变量时,需要在所有访问该变量的方法上加上synchronized。举例,A类内有 1个synchronized方法, 比如 add() , 一个非 synchronized方法 ,比如 subtract() ,2个方法内对同一共享变量进行操作,并不能保证线程安全。所以如果需要保证变量的线程安全性,需要对所有操作该变量的方法,添加synchronized锁。

2.2.1  同步方法;

可理解为对“该方法所属的对象加锁” ,一次只能一个线程拿到锁,开始执行。也就是说,在同一个时间片内,并发执行的线程(同时执行到当前方法的线程)只有一个可以运行,其他线程必须等待。所以一般效率比较低。

2.2.2  同步代码块:

同步代码块锁定的代码范围更小,多个并发线程更大灵活性更大,毕竟代码块外部的指令依旧可以执行。而且锁定代码块也会更快执行完成。

2.3  CAS机制:属于乐观锁机制,适合并发冲突比较少的场合。

  线程A 操作共享变量后,假定其他线程并没有操作该变量。则直接放回该变量。 如果内存的值不是预期值(也即是其他线程操作了该变量,虽然概率很低),则不做任何改变,返回 false。

2.3.1  机制说明:

1,操作变量后,和主内存对比,  失败后,一般开启继续重试。

2,重试的过程是,继续循环过程1,继续拉去新的共享变量,操作然后重新对比。 可理解为,总能找都一个时间片,没有存在并发冲突。

CAS 是 compare and swap 的简写,即比较并交换。它是指一种操作机制,而不是某个具体的类或方法。在 Java 平台上对这种操作进行了包装。在 Unsafe 类中,调用代码如下

unsafe.compareAndSwapInt(this, valueOffset, expect, update);

作为一种底层机制, CAS 在 Java 的原子类和并发包中有大量使用。

CAS 底层是靠调用 CPU 指令集的 cmpxchg 完成的。但是这种方案容易引发一个典型问题:ABA 问题 ,可以通过加版本号解决。

2.4  等待唤醒机制:或者称为“线程通信模型”

wait/notify 就是线程间的一种协作机制。

2.5  Atomic : 原子类

2. 6  Lock锁机制:

AQS是AbstractQueuedSynchronizer的缩写)

(后续补充,  还有补充代码实践演示。)

三, 其他一些相关概念:

悲观锁和乐观锁概念:

悲观锁:和独占锁是一个意思,它假设一定会发生冲突,因此获取到锁之后会阻塞其他等待线程。典型方案是synchronized方案

乐观锁:假设不会产生冲突,先去尝试执行某项操作,失败了再进行其他处理(一般都是不断循环重试),适用于同步冲突比较少的场合。典型方案是CAS方案

公平锁和非公平锁:

公平锁是指各个线程在加锁前先检查有无排队的线程,按排队顺序去获得锁。

非公平锁是指线程加锁前不考虑排队问题,直接尝试获取锁,获取不到再去队尾排队。

可重入锁和不可重入锁:

如果一个线程已经获取到了一个锁,那么它可以访问被这个锁锁住的所有代码块。不可重入锁与之相反。

死锁概念:两个线程相互等待的状态就形成了死锁。

Java多线程编程技术方案原理的更多相关文章

  1. Java多线程编程核心技术(三)多线程通信

    线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...

  2. Java多线程编程详解

    转自:http://programming.iteye.com/blog/158568 线程的同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Ja ...

  3. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

  4. Java多线程编程实战指南(核心篇)读书笔记(四)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76690961冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  5. Java多线程编程总结(精华)

    Java多线程编程总结 2007-05-17 11:21:59 标签:多线程 java 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http ...

  6. 《java多线程编程核心技术》(一)使用多线程

    了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...

  7. 《Java 多线程编程核心技术》- 笔记

    作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...

  8. Java多线程编程核心技术(二)对象及变量的并发访问

    本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...

  9. Java多线程编程核心技术(一)Java多线程技能

    1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...

  10. java多线程编程模式

    前言 区别于java设计模式,下面介绍的是在多线程场景下,如何设计出合理的思路. 不可变对象模式 场景 1. 对象的变化频率不高 每一次变化就是一次深拷贝,会影响cpu以及gc,如果频繁操作会影响性能 ...

随机推荐

  1. OpenMP Sections Construct 实现原理以及源码分析

    OpenMP Sections Construct 实现原理以及源码分析 前言 在本篇文章当中主要给大家介绍 OpenMP 当中主要给大家介绍 OpenMP 当中 sections construct ...

  2. STM32F0库函数初始化系列:PWM输出

    void TIM1_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_Time1BaseStructure; TIM_OCInitTypeDef TI ...

  3. RocketMQ - 生产者消息发送流程

    RocketMQ客户端的消息发送通常分为以下3层 业务层:通常指直接调用RocketMQ Client发送API的业务代码. 消息处理层:指RocketMQ Client获取业务发送的消息对象后,一系 ...

  4. centos7配置vue环境

    1.安装nodejs #下载源码 wget https://npm.taobao.org/mirrors/node/v14.15.4/node-v14.15.4-linux-x64.tar.xz #解 ...

  5. JMeter 常用的几种断言方法

    一.Jmeter 断言背景 在使用Jmeter进行性能测试或者接口自动化测试工作中,经常会用到的一个功能,就是断言.断言是在请求的返回层面增加一层判断机制.因为请求成功了,并不代表结果一定正确,因此需 ...

  6. 优秀PHP程序员技术成长之路

    按照了解的很多PHP/LNMP程序员的发展轨迹,结合个人经验体会,抽象出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段PHP程序员的技术要求,来帮助很多PHP程序做对照设定 ...

  7. vue学习笔记:环境搭建

    一.安装node.js node.js的官方地址为:https://nodejs.org/en/download/ 下载好安装包点击安装,基本就是下一步.下一步.... 安装完成后可以通过以下两种方式 ...

  8. mybatis:自定义映射关系resultMap

    创建表t_emp 定义实体类 package org.example.entity; public class Emp { private Integer empId; private String ...

  9. 第七周作业-N67044-张铭扬

    1. 说明自动化运维的路径,原理,实践方法. 所谓自动化运维是指通过将日常IT运维中大量的重复性工作(小到简单的日常检查.配置变更和软件安装,大到整个变更流程的组织调度)由过去的手工执行转为标准化.流 ...

  10. Linux驱动、应用调试技巧

    原文地址:https://hceng.cn/2019/04/08/Linux%E9%A9%B1%E5%8A%A8%E3%80%81%E5%BA%94%E7%94%A8%E8%B0%83%E8%AF%9 ...