本地线程

Java内存模型

半城伤御伤魂 提交于 2019-12-04 04:18:48
java内存模型划分 废话少说先上图: 1.程序计数器   程序计数器(Program Counter Register),也有称作为PC寄存器。想必学过汇编语言的朋友对程序计数器这个概念并不陌生,在汇编语言中,程序计数器是指CPU中的寄存器,它保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。   虽然JVM中的程序计数器并不像汇编语言中的程序计数器一样是物理概念上的CPU寄存器,但是JVM中的程序计数器的功能跟汇编语言中的程序计数器的功能在逻辑上是等同的,也就是说是用来指示 执行哪条指令的。   由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,因此,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰,否则就会影响到程序的正常执行次序。因此,可以这么说,程序计数器是每个线程所私有的。   在JVM规范中规定,如果线程执行的是非native方法

JVM——运行时数据区

为君一笑 提交于 2019-12-04 02:30:46
Java虚拟机运行时数据区 程序计数器 ​ 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。 ​ 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果线程正在执行的是 Native 方法,这个计数器值则为空( Undefinded )。此内存区域是唯一一个在Java虚拟机规范中没有规定任何 OOM 情况的区域。 Java虚拟机栈 ​ 线程私有,与线程的生命周期相同。Java虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储 局部变量表 、 操作数栈 、 动态链接 、 方法出口 等信息。每一个方法从调用至执行完成的过程,就对应一个栈帧在虚拟机栈中入栈到出栈的过程。 局部变量表 1。编译期可知的各种 基本数据类型 (boolean,byte,char,short,int,float,long,double), 2。 对象引用( reference 类型,对象起始地址的引用指针 或 对象的句柄 或与对象有关的其他位置) 3。

Linux 多线程编程(实现生产者消费者模型)

我是研究僧i 提交于 2019-12-04 01:47:08
Linux 多线程编程 线程分类 线程按照其调度者可以分为用户级线程和内核级线程两种。 内核级线程 在一个系统上实现线程模型的方式有好几种,因内核和用户空间提供的支持而有一定程度的级别差异。最简单的模型是在内核为线程提供了本地支持的情况,每个内核线程直接转换成用户空间的线程。这种模型称为“1:1线程模型(threading)”,因为内核提供的线程和用户的线程的数量是1:1。该模型也称为“内核级线程模型(kernel-level threading)”,因为内核是系统线程模型的核心。 Linux 中的线程就是“1:1线程模型”。在linux内核中只是简单地将线程实现成能够共享资源的进程。线程库通过系统调用 clone() 创建一个新的线程,返回的“进程”直接作为用户空间的线程。也就是说,在Linux上,用户调用线程和内核调用线程基本一致。 Linux的线程实现是在核外进行的,核内提供的是创建进程的接口do_fork()。内核提供了两个系统调用clone()和fork(),最终都用不同的参数调用do_fork()核内API。当然,要想实现线程,没有核心对多进程(其实是轻量级进程)共享数据段的支持是不行的,因此,do_fork()提供了很多参数,包括CLONE_VM(共享内存空间)、CLONE_FS(共享文件系统信息)、 CLONE_FILES(共享文件描述符表)、CLONE

【转载】对网络编程框架的理解

十年热恋 提交于 2019-12-03 20:13:24
对网络编程框架的理解 11 Apr 2018 网络框架是分布式系统中不可或缺的组件,我认为评价一个框架的好坏需要从性能和是否方便使用两方面考虑,在这总结下在参与pika、zeppelin、zeppelin-s3-gateway期间使用pink[1],调研优化pink,以及开发新网络框架Procyon[2]产生的一些关于网络框架的想法。 所谓框架应该就是提供了大部分代码,用户只需填充规定的部分代码即可,不用从头接触各种系统调用,所以网络框架一般情况下指的就是对TCP协议的socket各种封装,随着计算机处理能力的增强,以及应用规模的增大,程序员需要更好的利用硬件和操作系统提供的各种资源,所以随之出现了各种处理网络链接的模型,多线程,event loop等等,网络编程框架也就是对一种模型的实现,对于不同应用一般是通用的,方便了项目开发。 Eventbased Concurrency [3] 关于对一个客户端链接的处理很容易想到的一个办法就是每个链接建一个进程(后来改进为用线程)处理,这也是当时学操作系统时介绍的进程的一个作用(在FTP服务中,父进程接收新链接,然后建立子进程向客户端回复数据)。但是这种方法的缺点就是为不同客户端服务时会带来进程/线程切换的开销,从而无法服务太多的客户端。 这时出现了event-base的方法,在一个event loop中监听所有链接event

深入分析Synchronized原理

一曲冷凌霜 提交于 2019-12-03 20:06:27
前言 记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线程情况的百试不爽的良药。但是, 随着学习的进行我们知道在JDK1.5之前synchronized是一个重量级锁,相对于j.u.c.Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它 。 不过, 随着Javs SE 1.6对synchronized进行的各种优化后,synchronized并不会显得那么重了 。下面来一起探索synchronized的基本使用、实现机制、Java是如何对它进行了优化、锁优化机制、锁的存储结构等升级过程。 大家可以点击加群【JAVA架构知识学习讨论群】 473984645, (如多你想跳槽换工作,但是技术又不够,或者工作遇到了瓶颈,我这里有一个Java的免费直播课程,讲的是高端的知识点,只要有1-5年的开发工作经验可以加群找我要课堂链接。)注意:是免费的 没有开发经验的误入。 1 基本使用 Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。 Synchronized的作用主要有三个 : 原子性 :确保线程互斥的访问同步代码; 可见性 :保证共享变量的修改能够及时可见

并发编程71道

不羁岁月 提交于 2019-12-03 16:55:41
转 https://www.cnblogs.com/lfs2640666960/p/11488629.html 金九银十跳槽季已经开始,作为 Java 开发者你开始刷面试题了吗?别急,我整理了71道并发相关的面试题,看这一文就够了! 1、在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User)。 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(bool on);true则把该线程设置为守护线程,反之则为用户线程。Thread.setDaemon()必须在Thread.start()之前调用,否则运行时会抛出异常。 两者的区别: 虚拟机(JVM)何时离开,Daemon是为其他线程提供服务,如果全部的User Thread已经撤离,Daemon 没有可服务的线程,JVM撤离。也可以理解为守护线程是JVM自动创建的线程(但不一定),用户线程是程序创建的线程;比如JVM的垃圾回收线程是一个守护线程,当所有线程已经撤离,不再产生垃圾,守护线程自然就没事可干了,当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。 扩展:Thread Dump打印出来的线程信息,含有daemon字样的线程即为守护进程,可能会有:服务守护进程、编译守护进程、windows下的监听Ctrl

boost::thread线程管理

≯℡__Kan透↙ 提交于 2019-12-03 14:46:54
6.1. 概述 线程就是,在同一程序同一时间内允许执行不同函数的离散处理队列。 这使得一个长时间去进行某种特殊运算的函数在执行时不阻碍其他的函数变得十分重要。 线程实际上允许同时执行两种函数,而这两个函数不必相互等待。 一旦一个应用程序启动,它仅包含一个默认线程。 此线程执行 main() 函数。 在 main() 中被调用的函数则按这个线程的上下文顺序地执行。 这样的程序称为单线程程序。 反之,那些创建新的线程的程序就是多线程程序。 他们不仅可以在同一时间执行多个函数,而且这在如今多核盛行的时代显得尤为重要。 既然多核允许同时执行多个函数,这就使得对开发人员相应地使用这种处理能力提出了要求。 然而线程一直被用来当并发地执行多个函数,开发人员现在不得不仔细地构建应用来支持这种并发。 多线程编程知识也因此在多核系统时代变得越来越重要。 本章将介绍C++ Boost库 Boost.Thread ,它可以开发独立于平台的多线程应用程序。 6.2. 线程管理 在这个库最重要的一个类就是 boost::thread ,它是在 boost/thread.hpp 里定义的,用来创建一个新线程。下面的示例来说明如何运用它。 #include <boost/thread.hpp> #include <iostream> void wait(int seconds) { boost::this

这一次,终于系统的学习了 JVM 内存结构

こ雲淡風輕ζ 提交于 2019-12-03 13:55:19
摘自: https://www.cnblogs.com/jamaler/p/11797273.html 这一次,终于系统的学习了 JVM 内存结构 最近在看《 JAVA并发编程实践 》这本书,里面涉及到了 Java 内存模型,通过 Java 内存模型顺理成章的来到的 JVM 内存结构,关于 JVM 内存结构的认知还停留在上大学那会的课堂上,一直没有系统的学习这一块的知识,所以这一次我把《 深入理解Java虚拟机JVM高级特性与最佳实践 》、《 Java虚拟机规范 Java SE 8版 》这两本书中关于 JVM 内存结构的部分都看了一遍,算是对 JVM 内存结构有了新的认识。JVM 内存结构是指:Java 虚拟机定义了若干种程序运行期间会使用的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁,另一些则与线程一一对应,随着线程的开始而创建,随着线程的结束而销毁。具体的运行时数据区如下图所示: 在 Java 虚拟机规范中,定义了五种运行时数据区,分别是 Java 堆、方法区、虚拟机栈、本地方法区、程序计数器,其中 Java 堆和方法区是线程共享的。接下来就具体看看这 五种运行时数据区。 Java 堆(Heap) Java 堆是所有线程共享的一块内存区域,它在虚拟机启动时 就会被创建,并且单个 JVM 进程有且仅有一个 Java 堆。Java 堆是用来存放对象实例及数组

java面试小结——框架(hibernate、MyBatis、spring、Spring MVC)

ε祈祈猫儿з 提交于 2019-12-03 08:16:06
Hibernate 什么是ORM 对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;简单的说,ORM是通过使用描述对象和数据库之间映射的元数据(在Java中可以用XML或者是注解),将程序中的对象自动持久化到关系数据库中或者将关系数据库表中的行转换成Java对象,其本质上就是将数据从一种形式转换到另外一种形式。 持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些? 所谓”持久”就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。 持久层设计的目标包括: - 数据存储逻辑的分离,提供抽象化的数据访问接口。 - 数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。 - 资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。 - 数据抽象,提供更面向对象的数据操作。 持久层框架有: - Hibernate - MyBatis - TopLink - Guzz - jOOQ - Spring Data - ActiveJDBC Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗

JVM原理

 ̄綄美尐妖づ 提交于 2019-12-03 07:07:19
# JVM原理 # JVM->java虚拟机,解释器,负责将程序员编写的.java文件编译为多平台通用的字节码(.class)文件,最终将字节码解释给计算机执行 [JVM内存区域主要划分为“线程共享区”“非线程共享区”,比如,Method Area(方法区,non-heap)与Heap(堆),Direct Memory(运行时数据区域)是线程共享的,VM Stack(java方法栈,虚拟机栈),Native Method Stack(本地方法栈)和Program Counter Register(程序计数器)是非线程共享的] 2.JVM运行时初始分配方法区与堆,遇到线程时,分配程序计数器,虚拟机栈,本地方法栈,线程终止时,三者的内存空间会被释放(生命周期==所属线程生命周期),这也是为什么GC机制只会发生在“线程共享区”的原因。 来源: https://www.cnblogs.com/yh2two/p/11782320.html