线程池

池和回调函数

十年热恋 提交于 2020-03-15 13:55:12
池和回调函数 使用线程池和进程池的原因: 减少时间:在池中可以提前开几个线程线程不关闭,程序运行的时候可以直接使用线程,减少线启动和关闭的时间。 减少开销:有大量程序需要处理的时候如果使用多线程去处理,那么会需要开启很多的线程,如果超出CPU+1的数量,那么会造成程序执行效率低下。 但是如果使用线程池和进程池,开启固定的线程和进程来处理,则会减少开销,降低消耗。 concurrent.futures模块 python3,4模块之前进程池使用的是processing模块中的Pool类来实现的,线池threading模块中没有Pool类,如果使用需要开发者自己去编写。但是从python3.4之后的版本 进程和线程池都是通过使用concurrent.futures模块来进行的。 基本的使用: 导入模块:from concurrent_futures import ThreadPoolExecutor/ProcessPoolExecutor 实例化池对象: 线程池:tp = ThreadPoolExecutor() 进程池:pp = ProcessPoolExecutor() 提交任务:tp/pp.submit(func, *args, **kwargs) import time from threading import current_thread from concurrent

Java多线程:Linux多路复用,Java NIO与Netty简述

蓝咒 提交于 2020-03-15 10:11:48
JVM的多路复用器实现原理 Linux 2.5以前:select/poll Linux 2.6以后: epoll Windows: Winsock的select模型(感谢评论指正,仅Java NIO.2使用了Windows IOCP,由于Netty没有采用NIO.2此处不展开) Free BSD, OS X: kqueue 下面仅讲解Linux的多路复用。 Linux中的IO Linux的IO将所有外部设备都看作文件来操作,与外部设备的操作都可以看做文件操作,其读写都使用内核提供的系统调用,内核会返回一个文件描述符(fd, file descriptor),例如socket读写使用socketfd。描述符是一个索引,指向内核中一个结构体,应用程序对文件的读写通过描述符完成。 一个基本的IO,涉及两个系统对象:调用这个IO进程的对象,系统内核,read操作发生时流程如下: 通过read系统调用向内核发起读请求。 内核向硬件发送读指令,并等待读就绪。 内核把将要读取的数据复制到描述符所指向的内核缓存区中。 将数据从内核缓存区拷贝到用户进程空间中。 Linux I/O模型简介 阻塞I/O模型:最常用,所有文件操作都是阻塞的。 非阻塞I/O模型:缓冲区无数据则返回,一般采用轮询的方式做状态检查。 I/O复用模型:详细见下 信号驱动I/O:使用信号回调应用,内核通知用户何时开启一个I/O操作

to meet you Java多线程与并发

家住魔仙堡 提交于 2020-03-14 18:46:59
2: hotspot中对象在内存的布局是分3部分 对象头 实例数据 对其填充 这里主要讲对象头:一般而言synchronized使用的锁对象是存储在对象头里的,对象头是由Mark Word和Class Metadata Address组成 mark word存储自身运行时数据,是实现轻量级锁和偏向锁的关键,默认存储对象的hasCode、分代年龄、锁类型、锁标志位等信息。 由于对象头的信息是与对象定义的数据没有关系的额外存储成本,所以考虑到jvm的空间效率,mark word 被设计出一个非固定的存储结构,以便存储更多有效的数据,它会根据对象本身的状态复用自己的存储空间(轻量级锁和偏向锁是java6后对synchronized优化后新增加的) Monitor:每个Java对象天生就自带了一把看不见的锁,它叫内部锁或者Monitor锁(监视器锁)。上图的重量级锁的指针指向的就是Monitor的起始地址。 每个对象都存在一个Monitor与之关联,对象与其Monitor之间的关系存在多种实现方式,如Monitor可以和对象一起创建销毁、或当线程获取对象锁时自动生成,当线程获取锁时Monitor处于锁定状态。 Monitor是虚拟机源码里面用C++实现的 源码解读:_WaitSet 和_EntryList就是之前学的等待池和锁池,_owner是指向持有Monitor对象的线程

源码分析Dubbo网络通讯篇之NettyServer网络事件派发机制(Dispatch)

℡╲_俬逩灬. 提交于 2020-03-12 21:06:33
本节将主要学习Dubbo是如何使用Netty来实现网络通讯的。 从官网我们得知,Dubbo协议是使用单一长连接来进行网络传输,也就是说服务调用方持久与服务提供者建立一条连接,所有的服务调用调用信息通过。 一条TCP连接进行传输,在网络层至少要考虑如下问题: 服务端,客户端网络通讯模型(线程模型) 传输(编码解码、序列化)。 服务端转发策略等。 Dubbo服务端的网络启动流程,在上篇中已给出序列图,本节还是以该图为切入点,引入本文的两个主人公:NettyServer、NettyClient。 dubbo使用SPI机制,根据配置,可以支持如下框架实现网络通讯模型,例如netty3,netty4、mina、grizzly,本文重点分析基于Netty4的实现,包路径:dubbo-remoting-netty4。 从上面的流程图,NettyTransport的职责就是调用new NettyServer的构造方法,从而构建NettyServer对象,在深入NettyServer对象构造过程之前,先来看一下NettyServer的类继承层次: NettyServer构造函数: public NettyServer(URL url, ChannelHandler handler) throws RemotingException { // @1 super(url, ChannelHandlers

面试之线程池底层剖析

半世苍凉 提交于 2020-03-12 11:29:14
线程池类图 Executor==>ExcutorService==>AbstractExecutorService==>ThreadPoolExecutor来分析一下。 上面url继承类图,线程池的最顶层的接口是Executor,这个接口只有一个方法void execute(Runnable command) ExecutorService继承Executor,新增了submit(Runnable(Callable)),shutDown,shutDownNow等几个主要方法 AbstractExecutorService实现了上面的ExecutorService接口的若干个方法。 ThreadPoolExecutor继承AbstractExecutorService,实现了线程池的一些主要的方法execute(Runnable)。 AbstractExecutorService AbstractExecutorService实现了submit方法,代码如下: submit(Callable task)方法 public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor

黑马程序员_java多线程总结

[亡魂溺海] 提交于 2020-03-12 05:16:55
android培训 、 java培训 、期待与您交流! /* 多线程技术 java虚拟机允许程序并发地运行多个线程。 JVM启动至少有两个线程,一个是主线程(代码在mian方法中);另一个是负责垃圾回收机制的线程。 创建线程 方法一 在java.lang包中有一个Thread类 继承Thread类 步骤: 1,定义类继承Thread. 2,复写Threa类中的run方法; 目的:将自定义代码存储在run方法中,让线程运行。 3,调用start(),该方法有两个作用,就是启动线程,调用run方法。 */ // 例:三个窗口分别买票,每一个窗口卖10张票 class ThreadDemo extends Thread //定义类继承Thread. { public void run() //复习run方法 { int x=1; while(x<=10) { System.out.println(Thread.currentThread().getName()+"....."+x);//打印正在运行的线程 x++; } } } class Test { public static void main(String[] String) { new ThreadDemo().start();//创建第一个线程并运行 new ThreadDemo().start();//创建第二个线程并运行

线程池入门

依然范特西╮ 提交于 2020-03-12 03:27:09
什么是池,我们在开发中经常会听到有线程池啊,数据库连接池等等。 那么到底什么是池? 其实很简单,装水的池子就叫水池嘛,用来装线程的池子就叫线程池(废话),就是我们把创建好的N个线程都放在一个池子里面,如果有需要,我们就去取,不用额外的再去手动创建了 为什么要用线程池 按照正常的想法是,我们需要一个线程,就去创建一个线程,这样的想法是没错的,但是如果需要有N多个线程呢?那把创建线程的代码复制N多份?或者用for循环来创建?NO,这样不是不行,但是不好。 因为线程也是有生命周期的,创建与销毁线程都会对系统资源有很大的开销,创建线程需要向系统申请相应的资源,销毁线程又会对垃圾回收器造成压力 使用线程池的好处 加快响应速度,需要线程我们就去取,不用额外的创建,可以反复利用。 合理的利用CPU与内存资源,因为CPU与内存都不是无限的 可以把线程进行一个统一的管理 线程池的适用场景 在实际开发中,如果需要5个以上的线程,那么就应该使用线程池来完成工作 线程池的创建与停止 我们先来说线程池的创建,我们都知道,在Java中的对象都是有构造方法的,有些可以使用无参的构造方法来创建,有些就需要使用有参的构造方法来创建,线程池的创建就必须要往构造方法中传入参数,我们就先来了解一下线程池中的构造参数都是一些什么含义吧,否则你怎么知道你创建的线程池是一个什么样的运行规则呢 corePoolSize:(int

C++ 公共组件-线程池实现

我只是一个虾纸丫 提交于 2020-03-11 13:02:48
C++ 公共组件-线程池实现 线程池模型介绍 在处理大量并发任务的时候,如果按照传统的方式,一个请求一个线程来处理请求任务,大量的线程创建和销毁将消耗过多的系统资源,还增加了线程上下文切换的开销,而通过线程池技术就可以很好地解决这些问题。线程池技术通过在系统中预先创建一定数量的线程,当任务请求到来时从线程池中分配一个预先创建的线程去处理任务,线程在处理完任务之后还可以重用,不会销毁,而是等待下次任务的到来。这样,通过线程池能避免大量的线程创建和销毁动作,从而节省系统资源,这样做的一个好处是,对于多核处理器,由于线程会被分配到多个CPU,会提高并行处理的效率。另一个好处是每个线程独立阻塞,可以防止主线程被阻塞而使主流程被阻塞,导致其他的请求得不到响应的问题。 线程池分为半同步半异步线程池和领导者追随者线程池,本章将主要介绍半同步半异步线程池,这种线程池在实现上更简单,使用得比较多,也比较方便。半同步半异步线程池分成三层。如下图显示 第一层是同步服务层,它处理来自上层的任务请求,上层的请求可能是并发的,这些请求不是马上就会被处理,而是将这些任务放到一个同步排队层中,等待处理。第二层是同步排队层,来自上层的任务请求都会加到排队层中等待处理。第三层是异步服务层,这一层中会有多个线程同时处理排队层中的任务,异步服务层从同步排队层中取出任务并行的处理。

常用的线程池有哪些?

人盡茶涼 提交于 2020-03-10 10:37:06
newFixedThreadPool :创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小; newCachedThreadPool :创建一个可缓存的线程池,此线程池不会对线程池大小做限制,线程池大小完全依赖于 操作系统(或者说 JVM )能够创建的最大线程大小; newScheduledThreadPool :创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求; newSingleThreadExecutor :创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。 线程池能够带来三个好处 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。 第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定 性,使用线程池可以进行统一的分配,调优和监控。 来源: https://www.cnblogs.com/Yanss/p/12453894.html