本地线程

学习Java并发(01)基本概念

泪湿孤枕 提交于 2020-01-08 15:09:14
前言 在工作中时常接触到并发环境,只是现有的框架已经在底层封装好了,可以直接调用。但总会有一些奇特的场景需要自己手动实现并发,所以了解原理是很重要的。本文用于记录学习并发过程中重要的点或思考。 本文只讨论基本概念,旨在用较为详细易懂的文字记录自己对于并发的一些理解。 什么是并发 并发(Concurrency)是指系统在同一时间段可同时处理多个任务,而同一时刻只有一个任务处于运行状态。 实际上对于单核CPU而言无法实现真正的同时运行多个任务。但是由于CPU运算速度极快,在一个短的时间单位内(比如0.001秒)执行一个任务,执行完马上切换到下一个任务。这样宏观看起来就像是在同时运行多个任务了。 与 并行(Parallel) 的区别:并行是指同一时刻可以同时运行多个任务。现代多核处理器都支持并行运算。并发强调系统支持多个任务同一时刻存在;并行强调系统支持多个任务同时运行。 CPU核心数 可以理解为多处理器,双核CPU从程序的角度来看就等于可共享资源的两个单核处理器。对于单核处理器而言,任一时刻只能处理一个任务;然而多核处理器可以在同一时刻同时处理多个任务。由于现在的CPU基本都支持所谓的 超线程 ,使得一个物理核心可以逻辑上实现两个任务的同时运行(比如Intel的i5处理器通常都是4核8线程,6核12线程),所以程序角度来看一个核心,系统在同一时刻可以同时运行的任务数为:CPU超线程数

Java 并发基础常见面试题总结

本小妞迷上赌 提交于 2020-01-07 23:24:19
Java 并发基础常见面试题总结 1. 什么是线程和进程? 1.1. 何为进程? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。 如下图所示,在 windows 中通过查看任务管理器的方式,我们就可以清楚看到 window 当前运行的进程(.exe 文件的运行)。 1.2. 何为线程? 线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。 Java 程序天生就是多线程程序,我们可以通过 JMX 来看一下一个普通的 Java 程序有哪些线程,代码如下。 public class MultiThread { public static void main(String[] args) { // 获取 Java 线程管理 MXBean ThreadMXBean threadMXBean =

ASP.NET MVC 线程和并发

馋奶兔 提交于 2020-01-07 19:24:19
我也想过跳过C#高级知识点概要直接讲MVC,但经过前思后想,还是觉得有必要讲的。我希望通过自己的经验给大家一些指引,带着大家一起走上ASP.NET MVC大牛之路,少走弯路。同时也希望能和大家一起交流,这样也能发现我自己的不足,对我自己的帮助也是非常大的。 建议大家对C#撑握的不错的时候,可以去看一些开源项目。走技术这条路,就要耐得住寂寞(群里双休日说要让群主找妹子进群的人必须反思),练好内功。不撑握C#高级知识点,别想看懂优秀的开源项目,更别指望吸收其编程思想;你的水平,随时可以被一个实习生代替!切记不能浮躁! 本文讲线程和并发,这块知识点太多太多了,不可能用一篇文章写的面面具到(本身主题就是C#高级知识概要嘛),我所了解的也有限。但对于Web开发,我想本文的知识点应该足够,如果后面有遇到本文没讲的,后面再补充吧。 本文目录: 线程的简单使用 并发和异步的区别 并发控制 - 锁 线程的信号机制 线程池中的线程 案例:支持并发的异步日志组件 结语 线程的简单使用 常见的并发和异步大多是基于线程来实现的,所以本文先讲线程的简单使用方法。 使用线程,我们需要引用System.Threading命名空间。创建一个线程最简单的方法就是在 new 一个 Thread,并传递一个ThreadStart委托(无参数)或ParameterizedThreadStart委托(带参数),如下:

那里找115资源那有卖的

江枫思渺然 提交于 2020-01-07 12:39:36
【十 薇:PPS33A】【持续更新】【品种繁多】【任意挑选】【质量有保障】了解JVM内存结构的目的 在Java的开发过程中,因为有JVM自动内存管理机制,不再需要像在C、C++开发那样手动释放对象的内存空间,不容易出现内存泄漏和内存溢出的问题。但是,正是由于把内存管理的权利交给了JVM,一旦出现内存泄漏和内存溢出方面的问题,如果不了解JVM是如何使用内存的,不了解JVM的内存结构是什么样子的,就很难找到问题的根源,就更难以解决问题。 JVM内存结构简介 在JVM所管理的内存中,大致分为以下几个运行时数据区域: 程序计数器:当前线程所执行的字节码的行号指示器。 虚拟机栈:Java方法执行的内存模型,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。 本地方法栈:本地方法执行的内存模型,和虚拟机栈非常相似,其区别是本地方法栈为JVM使用到的Native方法服务。 堆:用于存储对象实例,是垃圾收集器管理的主要区域。 方法区:用于存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 其中,黄色区域的程序计数器、虚拟机栈和本地方法栈是线程私有的,红色区域的堆和方法区是线程共享的。下面我们逐一详细分析各个区域。 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它记录了当前线程所执行的字节码的行号。在JVM的概念模型里

多线程安全和内存模型

狂风中的少年 提交于 2020-01-07 08:42:26
同步 方法 使用 的是什么锁 ? synchronized 修饰方法使用锁是当前this锁。 synchronized 修饰静态方法使用锁是当前类的字节码文件 Threadlocal 什么是 Threadlocal ThreadLocal提高一个线程的局部变量,访问某个线程拥有自己局部变量。 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 实现原理: ThreadLoca通过map集合 Map.put(“当前线程”,值); J ava 内存模型 共享内存模型指的就是Java内存模型(简称JMM), JMM 决定一个线程对共享变量的写入时 ,能 对另一个线程可见 。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系: 线程之间的共享变量存储在主内存( main memory )中,每个线程都有一个私有的本地内存( local memory ),本地内存中存储了该线程以读 / 写共享变量的副本 。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。 什么是 J ava 内存模型: java 内存模型 简称 jmm , 定 义了 一个线程 对 另一个 线程可见。 共享 变量存放在主内存中

Java堆栈跟踪工具jstack

☆樱花仙子☆ 提交于 2020-01-06 16:15:37
jstack(Stack Trace for Java) 概述 作用:生成虚拟机当前时刻的线程快照。 线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。 主要是定位出现长时间停顿的原因,如线程间死锁,死循环,请求外部资源导致的长时间等待。 命令解析 jstack [ option ] vmid -F 正常输出的请求不被相应时,强制输出线程堆栈 -l 除堆栈外,显示关于锁的附加信息 -m 如果调用的本地方法,可以显示C/C++的堆栈 来源: CSDN 作者: 小汪4code 链接: https://blog.csdn.net/qq_32527287/article/details/103843521

Java并发:volatile内存可见性和指令重排

纵然是瞬间 提交于 2020-01-06 00:32:44
volatile两大作用 1、保证内存可见性 2、防止指令重排 此外需注意volatile 并不保证操作的原子性。 (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模型规定,对于多个线程共享的变量,存储在主内存当中,每个线程都有自己独立的工作内存(比如CPU的寄存器),线程只能访问自己的工作内存,不可以访问其它线程的工作内存。 工作内存中保存了主内存共享变量的 副本 ,线程要操作这些共享变量,只能通过操作工作内存中的副本来实现,操作完毕之后再同步回到主内存当中。 如何保证多个线程操作主内存的数据完整性是一个难题,Java内存模型也规定了工作内存与主内存之间交互的协议,定义了8种原子操作: (1) lock:将主内存中的变量锁定,为一个线程所独占 (2) unclock:将lock加的锁定解除,此时其它的线程可以有机会访问此变量 (3) read:将主内存中的变量值读到工作内存当中 (4) load:将read读取的值保存到工作内存中的变量副本中。 (5) use:将值传递给线程的代码执行引擎 (6) assign:将执行引擎处理返回的值重新赋值给变量副本 (7) store:将变量副本的值存储到主内存中。 (8) write:将store存储的值写入到主内存的共享变量当中。 通过上面Java内存模型的概述,我们会注意到这么一个问题

volatile和synchronized的区别

和自甴很熟 提交于 2020-01-05 03:41:14
volatile和synchronized特点 首先需要理解线程安全的两个方面: 执行控制 和 内存可见 。 执行控制 的目的是控制代码执行(顺序)及是否可以并发执行。 内存可见 控制的是线程执行结果在内存中对其它线程的可见性。根据 Java内存模型 的实现,线程在具体执行时,会先拷贝主存数据到线程本地(CPU缓存),操作完成后再把结果从线程本地刷到主存。 synchronized 关键字解决的是执行控制的问题,它会阻止其它线程获取当前对象的监控锁,这样就使得当前对象中被 synchronized 关键字保护的代码块无法被其它线程访问,也就无法并发执行。更重要的是, synchronized 还会创建一个 内存屏障 ,内存屏障指令保证了所有CPU操作结果都会直接刷到主存中,从而保证了操作的内存可见性,同时也使得先获得这个锁的线程的所有操作,都 happens-before 于随后获得这个锁的线程的操作。 volatile 关键字解决的是内存可见性的问题,会使得所有对 volatile 变量的读写都会直接刷到主存,即保证了变量的可见性。这样就能满足一些对变量可见性有要求而对读取顺序没有要求的需求。 使用 volatile 关键字仅能实现对原始变量(如boolen、 short 、int 、long等)操作的原子性,但需要特别注意, volatile 不能保证复合操作的原子性,即使只是

JMM和happens-before原则

萝らか妹 提交于 2020-01-05 03:35:26
JMM:   Java Memory Model(Java内存模型),围绕着在并发过程中如何处理 可见性 、 原子性 、 有序性 这三个特性而建立的模型。 可见性:   JMM提供了volatile变量定义、final、synchronized块来保证可见性。   例如:线程a在将共享变量x=1写入主内存的时候,如何保证线程b读取共享变量x的值为1,这就是JMM做的事情。JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。 原子性:   JMM提供保证了访问基本数据类型的原子性(其实在写一个工作内存变量到主内存是分主要两步:store、write),但是实际业务处理场景往往是需要更大的范围的原子性保证,所以模型也提供了 synchronized 块来保证。 有序性:   这个概念是相对而言的,如果在本线程内,所有的操作都是有序的,如果在一个线程观察另一个线程,所有的操作都是无序的,前句是“线程内表现为串行行为”,后句是“指令的重排序”和“工作内存和主内存同步延迟”现象,模型提供了 volatile和synchronized来保证线程之间操作的有序性 。 重排序:   在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序(编译器、处理器),就是因为这些重排序,所以可能会导致多线程程序出现内存可见性问题(数据安全问题)和有序性问题。  

Java多线程编程(3)--线程安全性

核能气质少年 提交于 2020-01-05 03:31:10
一.线程安全性   一般而言,如果一个类在单线程环境下能够运作正常,并且在多线程环境下,在其使用方不必为其做任何改变的情况下也能运作正常,那么我们就称其是线程安全的。反之,如果一个类在单线程环境下运作正常而在多线程环境下则无法正常运作,那么这个类就是非线程安全的。因此, 一个类如果能够导致竞态,那么它就是非线程安全的;而一个类如果是线程安全的,那么它就不会导致竞态。下面是《Java并发编程实战》一书中给出的对于线程安全的定义: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。   使用一个类的时候我们必须先弄清楚这个类是否是线程安全的。因为这关系到我们如何正确使用这些类。Java标准库中的一些类如ArrayList、HashMap和SimpleDateFormat,都是非线程安全的,在多线程环境下直接使用它们可能导致一些非预期的结果,甚至是一些灾难性的结果。一般来说,Java标准库中的类在其API文档中会说明其是否是线程安全的(没有说明其是否是线程安全的,则可能是也可能不是线程安全的)。   从线程安全的定义上我们不难看出,如果一个线程安全的类在多线程环境下能够正常运作,那么它在单线程环境下也能正常运作。既然如此