本地线程

优化线程池

五迷三道 提交于 2020-02-23 13:42:55
  线程池初始时其池内只有一个线程。随着任务的分配,线程池管理器就会向池内“注入”新线程来满足工作负荷的需要,直到最大数量的限制。在足够的非活动时间之后,线程池管理器在认为“回收”一些线程能够带来更好的吞吐量时进行线程回收。   可以通过调用 ThreadPool.SetMaxThreads 方法来设置线程池可以创建的线程上限;默认如下: Framework 4.0,32位环境下:1023 Framework 4.0,64位环境下:32768 Framework 3.5:每个核心 250 Framework 2.0:每个核心 25   (这些数字可能根据硬件和操作系统不同而有差异。)数量这么多是因为要确定阻塞(等待一些条件,比如远程计算机的相应)的线程的条件是否被满足。   也可以通过 ThreadPool.SetMinThreads 设置线程数量下限。下限的作用比较奇妙:它是一种高级的优化技术,用来指示线程池管理器在达到下限之前不要延迟线程的分配。当存在阻塞线程时,提高下限可以改善程序并发性。   默认下限数量是 CPU 核心数,也就是能充分利用 CPU 的最小数值。在服务器环境下(比如 IIS 中的 ASP.NET),下限数量一般要高的多,差不多 50 或者更高。 最小线程数量是如何起作用的?   将线程池的最小线程数设置为 x 并不是立即创建至少 x 个线程

Java 分支合并(ForkJoin)

我们两清 提交于 2020-02-23 11:21:47
简介:Fork/Join是由Java 7提供的并行执行任务框架,思路就是任务切分,结果合并,同时利用工作窃取机制, 目的是提高效率 。 1. 概念   A. 分而治之:即将任务划分为多个子任务,然后并行的执行这些子任务,等所有子任务都结束的时候,再合并成最终结果;   B. 工作窃取:当一个工作线程的本地没有任务去运行的时候,它将使用先进先出(FIFO)的规则尝试随机的从别的工作线程中拿一个任务去运行, 工作开始从头,窃取从尾 。 2. 核心类   A. ForkJoinPool是用于执行ForkJoinTask任务的执行池,维护了一个队列数组;   B. WorkQueue是ForkJoinPool的一个内部类;   C. ForkJoinWorkPool是用于执行任务的线程,每一个线程都有对应的一个WorkQueue;   D. ForkJoinTask代表正在ForkJoinPool中运行的任务     fork:安排任务异步执行,即创建一个子任务,     join:当任务完成后返回计算结果,     invoke:开始执行,如果计算没有完成,就会等待; 3. RecursiveTask和RecursiveAction的区别   A. RecursiveTask有返回值,而RecursiveAction没有返回值 来源: https://www.cnblogs.com

吃透Netty源码系列三十二之Recycler细节解析一

扶醉桌前 提交于 2020-02-22 23:41:52
吃透Netty源码系列三十二之Recycler细节解析一 Recycler 一些配置属性 简单例子入手 Recycler初始化 DELAYED_RECYCLED threadLocal Stack构造方法 处理器回收recycle(this) stack.push pushNow当前线程是Stack的所属线程 dropHandle pushLater当前线程不是Stack的所属线程 newWeakOrderQueue创建队列 Head链接管理者 Link具体存对象 Head.reserveSpaceForLink为Link申请空间 WeakOrderQueue构造方法 stack.setHead(queue) 设置头结点 queue.add加入队列 head.newLink创建链接 Recycler 首先他是个抽象类,有个抽象方法,创建对象,也就是说在对象池没有对象的时候得能创建对象: protected abstract T newObject ( Handle < T > handle ) ; 他与对象池配合使用,比如 ObjectPool 中的 RecyclerObjectPool : private static final class RecyclerObjectPool < T > extends ObjectPool < T > { private final

线程安全性-可见性

a 夏天 提交于 2020-02-22 05:05:26
导致共享变量在线程间不可见的原因 线程交叉执行;重排序结合线程交叉执行;共享变量更新后的值没有在工作内存与主存间及时更新 JMM关于synchronized的两条规定 线程解锁前,必须把共享变量的最新值刷新到主内存;线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主存中重新读取最新的值(注意加锁和解锁是同一把锁) 可见性-volatile 通过加入 内存屏障 和 禁止重排序 优化来实现; 对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量刷到之内存; 对volatile变量读操作时,会在读操作前加入一条load屏障指令,从主内存中读取共享变量。 可见性-volatile读 可见性-volatile读 可见性-volatile使用 当变量作为多个线程之间的交流变量 valatile boolean inited = false ; //线程1 context = loadContext ( ) ; inited = true ; //线程2 while ( ! inited ) { sleep ( ) ; } doSomethingWithConfig ( context ) ; 这段代码中,线程1的context=loadContext()和inited=true的操作不一定会按着代码逻辑顺序来的

主从数据库详解

倖福魔咒の 提交于 2020-02-21 19:20:32
数据库集群和主从数据库最本质的区别, 其实也就是data-sharing和nothing-sharing的区别。集群是共享存储的 。 主从复制中没有任何共享 。每台机器都是独立且完整的系统。 目录: 一、什么是主从复制 二、主从复制的作用(重点) 三、主从复制的原理(重中之重) 四、必问面试题干货分析(最最重要的点) 一、什么是主从复制 ? 主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库。 二、主从复制的作用(好处,或者说为什么要做主从)重点 ! 1、做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。 2、架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。 3、读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。 三、主从复制的原理(重中之重,面试必问): 1.数据库有个bin-log二进制文件,记录了所有sql语句。 2.我们的目标就是把主数据库的bin-log文件的sql语句复制过来。 3.让其在从数据的relay

Jmeter学习(一)—Jmeter使用入门

做~自己de王妃 提交于 2020-02-19 19:34:10
一 Jmeter安装 1 安装并配置JDK 2 登录 http://jmeter.apache.org/download_jmeter.cgi ,根据自己平台,下载对应文件 3 解压后即可直接运行 /bin/jmeter.bat 注意:打开的时候会有两个窗口,JMeter的命令窗口和JMeter的图形操作界面,不可以关闭命令窗口。 二 安装插件管理器 1 插件下载地址: http://jmeter-plugins.org/downloads/all/ 2 下载插件管理器后放到 apache-jmeter-xxx\lib\ext目录,然后重启Jmeter。 三 Jmeter的目录结构 1 /bin 目录(常用文件介绍) examples:目录下包含Jmeter使用实例 ApacheJMeter.jar:JMeter源码包 jmeter.bat:windows下启动文件 jmeter.sh:Linux下启动文件 jmeter.log:Jmeter运行日志文件 jmeter.properties:Jmeter配置文件 jmeter-server.bat:windows下启动负载生成器服务文件 jmeter-server:Linux下启动负载生成器文件 2 /docs目录——Jmeter帮助文档 3 /extras目录——提供了对Ant的支持文件,可也用于持续集成 4 /lib目录—

2020春招——JVM复习总结篇

≡放荡痞女 提交于 2020-02-19 05:00:40
一. 基本概念: JVM是可运行Java代码的假想计算机 ,包括一套字 节码指令集、一组寄存器、一个栈、一个垃圾回收堆 和 一个存储方法域 。JVM 是运行在操作系统之上的,它与硬件没有直接的交互。 二. 运行过程: 我们都知道 Java 源文件,通过编译器,能够生产相应的.Class 文件,也就是字节码文件,而字节码文件又通过 Java 虚拟机中的解释器,编译成特定机器上的机器码 。也就是如下: ① Java 源文件—->编译器—->字节码文件 ② 字节码文件—->JVM—->机器码 每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。 三. 线程 这里所说的线程指程序执行过程中的一个线程实体。JVM 允许一个应用并发执行多个线程。Hotspot JVM 中的 Java 线程与原生操作系统线程有直接的映射关系。 当线程本地存储、缓冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。Java 线程结束,原生线程随之被回收。操作系统负责调度所有线程,并把它们分配到任何可用的 CPU 上。当原生线程初始化完毕,就会调用 Java 线程的 run() 方法

synchronized和volatile的区别

你说的曾经没有我的故事 提交于 2020-02-18 22:21:37
一、控制区别    首先我们要了解一下是什么是控制层面的区别,这里提到两点:   1.执行控制 目的是 控制代码执行(顺序) 及是否可以并发执行。   2.内存可见控制 线程执行结果在 内存中对其它线程的可见性 。根据Java内存模型的实现,线程在具体执行时,会先拷贝主存数据到线程本地(CPU缓存), 操作完成后再把结果从线程本地刷到主存 二、synchronized(执行控制)   1.synchronized会阻止其他线程获取当前的锁。   2.并且 synchronized 会将数据直接刷到主存,保证数据的可见性,同时也使得这个锁线程的所有操作都happends-before于之后获得这个锁的线程的操作。 三、volatile(内存可见性控制)   1.直接将数据刷到主存,保证内存可见性。   2.禁止指令重排 ("为了提高性能,编译器和处理器会对指令做重排序")   3.具有可见性、有序性,不具备原子性。   注“ 内存屏障指令保证了所有CPU操作结果都会直接刷到主存中。 将刷出所有在Barrier之前写入 cache 的数据,因此,任何CPU上的线程都能读取到这些数据的最新版本。 四、两者之间的区别   1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量

JVM内存结构

和自甴很熟 提交于 2020-02-18 22:20:51
所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能问题,那么这些问题就会变的非常常见,了解JVM内存也是为了服务器出现性能问题的时候可以快速的了解那块的内存区域出现问题,以便于快速的解决生产故障。 先看一张图,这张图能很清晰的说明JVM内存结构布局。 Java的内存结构: JVM内存结构主要有三大块:堆内存、方法区和栈。堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分成三部分,Eden空间、From Survivor空间、To Survivor空间,默认情况下年轻代按照8:1:1的比例来分配; 方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆);栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。 在通过一张图来了解如何通过参数来控制各区域的内存大小 控制参数 -Xms设置堆的最小空间大小。 -Xmx设置堆的最大空间大小。 -XX:NewSize设置新生代最小空间大小。 -XX:MaxNewSize设置新生代最大空间大小。 -XX:PermSize设置永久代最小空间大小。 -XX:MaxPermSize设置永久代最大空间大小。 -Xss设置每个线程的堆栈大小。

NodeJS开发指南:读书笔记随谈之一

為{幸葍}努か 提交于 2020-02-18 21:28:52
这本书是市面上讲nodejs的一本不可多得的入门书,当初想学 nodejs的时候,找了半天,终于找到了这本好书,随后一发不可收拾,花了一两天的功夫就看玩了,感觉作者系统功力深厚,以下只是偶的一些摘要,权当心得体会。 书里说nodejs的核心特性是异步IO,事件驱动,任何IO操作都是由事件来驱动的。 说到异步IO又不得不来看看操作系统的 线程与阻塞 。 什么是阻塞呢, 线程在执行中遇到磁盘读写或者数据库通讯,网络通讯这种耗时比较多的时候,操作系统将会剥夺此线程的CPU资源,并暂停此线程,转而去执行别的线程,此线程调度方式称为阻塞 。当 I/O操作完成之后,操作系统又恢复此线程,让其继续执行,这种I/O模式通常称为同步I/O或者阻塞式I/O。 异步式IO或者非阻塞式I/O则针对所有操作采取不阻塞的方式,当线程遇到IO操作的时候,不会以阻塞的方式等待IO操作完成或者数据的返回,而是将IO操作发送给操作系统,然后接着执行下一个操作,当操作系统执行完IO操作之后,将是事件的方式通知执行IO的线程,线程会在特定的时候执行这个事件。这一切的前提条件就是,系统需要一个事件循环,以不断的去查询有没有未处理的事件,然后给预处理。 阻塞方式下,一个线程只能处理一个任务,要想提高系统的吞吐量,必须使用多线程 ;而非阻塞情况下,一个线程永远在执行计算,CPU使用率几乎100%,IO以事件的方式通知