线程和线程池

线程池--jdk和tomcat线程池 1. jdk线程池: 创建方式: 有界队列:eg-- new ArrayBlockingQueue(10); 先拿任务数和corePoolSize比较,任务过多再去和队列比较,任务还多再去跟maximumPoolSize比较,最后执行拒绝策略。无界队列:eg-- new LinkedBlockingQueue(); 默认的capacity为Integer.MAX_VAL 阅读详情

这篇博客中简单介绍了下线程和线程池,今天主要 从示例上更加了解线程和线程池的工作
http://blog.youkuaiyun.com/androidxiaogang/article/details/49682885
文章为自己搜索总结,加上自己的一点看法,如果有误,欢迎指正。

1、进程,线程,多线程

从普通PC应用上来讲:
开个QQ,开了一个进程,在QQ的这个进程里,发送消息或者下载文件之类的,这就是打了线程,我们可能下载多个文件时,就会用到多线程。

从Android上来讲:
当我们点击应用图标时,就是开了进程,然后在main()方法后,打开主界面什么之类(activity,fragment之类的)这是主线程(UI线程),我们可能在这些界面上请求数据之类的,这就要用子线程(如果多个线程的话,就使用多线程,或者线程池)

1、一个进程启动后,它至少有一个线程,这个线程就是主线程。然后这个线程可以创建更多线程,比如说子线程,线程池之类的

2、应用程序不能脱离线程,每一个事件都在主线程或者子线程中运行。进程由线程组成。

2、Java,Android中的主线程

1、当java程序开始运行的时候,程序会创建一个主线程,这个主线程的开启是在main()主函数运行时确定的。

2、Android是由java代码写的,与java一样,都是在main()方法中启动主线程(UI)线程的,一个android应用只有一个Main()函数,Main()函数是应用程序的入口。android中的Main()函数是在framework中的ActivityManagerService(AMS)中的ActivityThread中进行了封装。

注:android和java一样,main函数都是程序的入口,都只有一个,很多人认为android中有很多main函数,就像一个Activity,其实Activity只是一个基本的java类一样,android的framework层封装了Main()函数,不对外暴漏。也就是android中只有一个main函数,在启动main函数时这创建主线程(UI线程)在这个线程中创建Activity,Fragment,Service等。当我们请求后台数据时要开子线程,数据回来后,在主线程中刷新界面。

3、线程

1、线程的创建方式

  1. 继承Thread类创建线程类
  2. 实现Runnable接口创建线程类
  3. jdk1.5后提供一个Callable接口实现线程类

2、线程的生命周期

这里写图片描述
1、新建 new Thread
当new一个新的线程的时候,该线程处于新建状态,由JVM分配内存,程序不会执行线程体中的内容。

2、调用start()方法后,处理就绪
启动线程,是调用start()方法,而不是run()方法,调用run()方法与调用一个普通的java方法没有区别。而不是启动线程的方法。

3、运行或者阻塞状态
运行到阻塞状态:

  1. 线程调用sleep(),join(),wait(),notify()方法,主动放弃处理器资源。
  2. 线程调用IO方法返回
  3. 线程在收到notify通知
  4. 线程中调用resume
  5. 等待同步锁

从阻塞到就绪状态

  1. 线程调用sleep(),join(),wait(),notify()方法结束
  2. 线程调用IO方法,返回前阻塞状态
  3. 线程在等待notify通知
  4. 线程中调用suspend方法(挂起线程,容易引起死锁)
  5. 获取到同步锁

4、死亡状态
1. run方法执行完毕
2. 异常
3. 调用了stop方法结束当前线程(容易导致死锁)

几个重要的方法

1、join():当在某个程序执行中调用了join()方法时,调用线程将被阻塞,直到被join()的线程执行完毕。

2、sleep()和yield()的区别:
sleep():是让当前的线程暂停,进行阻塞状态,在进入sleep()的时候内,该线程不会得到执行的机会。这样就给其他线程带来执行机会。
yield():与sleep()方法相似,但不会阻塞当前线程。它将线程转为就绪状态

4、线程同步

多个线程同时访问时就会出现线程安全问题,比如卖票,如果不进行线程控制,可能把0,-1张票卖出去。

同步代码块:用synchronized修饰的代码块

同步方法:用synchronized修饰的方法

5、线程通信

java中提供一些机制来保证线程协调运行。
wait(),notify()和notifyAll()方法要求在调用时线程已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或synchronized块中。

1、wait():使当前线程等待。直到其他线程用同步监视器(synchronized)的notify()或者notifyAll()方法。
2、notify()唤醒在些同步监视器(synchronized)上等待的单个线程。
3、notifyAll()唤醒在些同步监视器(synchronized)上等待的所有线程。
下面,通过一个示例来演示线程间的通信
示例:我们开启两个线程,一个线程打印1,另一个线程打印2
要求打印结果是:12121212….轮流打印
这里写图片描述
代码如下:

public class Number {
    private  int i=1;
    public Number(){

    }
    public synchronized  void printFisrt()  {
        System.out.print(1);
        //先唤醒其他同步监视器下的线程,然后当前线程处于阻塞状态;
        //如果先调用wait()然后调用notify的话会发生死锁。
        notify();
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    public synchronized  void printSecond()  {
        System.out.print(2);
        //先唤醒其他同步监视器下的线程,然后当前线程处于阻塞状态;
        notify();
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

打印1的线程FirstThread代码

public class FisrtThread extends Thread {
    Number n;

    public FisrtThread(Number n) {
        this.n = n;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            n.printFisrt();
        }
    }
}

打印2的线程SecondThread代码

public class SecondThread extends Thread {
    Number n;
    public SecondThread(Number n){
        this.n=n;
    }
    @Override
    public void run() {
     for(int i=0;i<10;i++){
         n.printSecond();
     }
    }
}

测试代码如下:

public class ThreadDemo {
    public static void main(String[] args) {
        Number n = new Number();
        Thread t1 = new FisrtThread(n);
        Thread t2 = new SecondThread(n);
        t1.start();
        t2.start();
    }
}

这里写图片描述

6、线程池

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
适用情况:
大量短小的任务。Web 服务器、数据库服务器、文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务。请求以某种方式到达服务器,这种方式可能是通过网络协议(例如 HTTP、FTP 或 POP)、通过 JMS 队列或者可能通过轮询数据库。不管请求如何到达,服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的。

线程池的好处:
1、提高性能(减少线程的创建与销毁,对于一些短小的请求,线程的创建和销毁,比线程使用更耗费内存)
2、有效的集中控制并发的数量,容易管理维护。
3、根据需求,手动设计线程池的大小。

线程池的工作原理:
jdk1.5提供创建线程池的源代码如下:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
       if (workQueue == null || threadFactory == null || handler == null)
             throw new NullPointerException();
         this.corePoolSize = corePoolSize;
         this.maximumPoolSize = maximumPoolSize;
         this.workQueue = workQueue;
         this.keepAliveTime = unit.toNanos(keepAliveTime);
         this.threadFactory = threadFactory;
         this.handler = handler;
     }

1、corePoolSize :核心运行的poolSize,也就是当超过这个范围的时候,就需要将新的 Runnable 放入到等待队列 workQueue 中了,我们把这些Runnable就叫做要去执行的任务吧。

2、maximumPoolSize :一般你用不到,当大于了这个值就会将 任务 由一个丢弃处理机制来处理,但是当你发生: newFixedThreadPool 的时候, corePoolSize 和 maximumPoolSize 是一样的,而 corePoolSize 是先执行的,所以他会先被放入等待队列,而不会执行到下面的丢弃处理中,看了后面的代码你就知道了。

3、workQueue :等待队列,当达到corePoolSize的时候,就向该等待队列放入线程信息(默认为一个 LinkedBlockingQueue ),运行中的线程属性为: workers ,为一个 HashSet ;我们的 Runnable 内部被包装了一层,后面会看到这部分代码;这个队列默认是一个无界队列(你也可以设定一个有界队列),所以在生产者疯狂生产的时候,考虑如何控制的问题。

4、keepAliveTime :默认都是0,当线程没有任务处理后,保持多长时间,当你使用: newCachedThreadPool() ,它将是60s的时间。这个参数在运行中的线程从 workQueue 获取任务时,当(poolSize >corePoolSize || allowCoreThreadTimeOut)会用到,当然 allowCoreThreadTimeOut 要设置为true,也会先判定 keepAliveTime 是大于0的,不过由于它在 corePoolSize 上采用了 Integer.MAX_VALUE ,当遇到系统遇到瞬间冲击, workers 就会迅速膨胀,所以这个地方就不要去设置 allowCoreThreadTimeOut =true,否则结果是这些运行中的线程会持续60s以上;另外,如果corePoolSize的值还没到Integer.MAX_VALUE,当超过那个值以后,这些运行中的线程,也是

5、threadFactory :是构造Thread的方法,你可以自己去包装和传递,主要实现 newThread 方法即可;

6、handler :也就是参数 maximumPoolSize 达到后丢弃处理的方法,java提供了5种丢弃处理的方法,当然你也可以自己根据实际情况去重写,主要是要实现接口: RejectedExecutionHandler 中的方法: public void rejectedExecution(Runnabler, ThreadPoolExecutor e) java默认的是使用:AbortPolicy,他的作用是当出现这中情况的时候会抛出一个异常;

参考博客
http://www.tuicool.com/articles/7ZzENj

IO型线程池和CPU型线程池 IO型线程池:适合处理I/O密集型任务,配置较多的线程来应对高并发I/O操作。CPU型线程池:适合处理计算密集型任务,配置的线程数接近CPU核心数,以充分利用CPU资源。选择合适的线程池配置可以显著提高系统性能和响应速度,在实际项目中需要根据任务特性进行合理选择。 阅读详情

相关推荐

Ansys Electronics Desktop仿真——HFSS线圈寄生电阻,电感

Ansys Electronics Desktop仿真——HFSS线圈寄生电阻,电感

冲击10w 1万+

线程池研发学习笔记

可以直接叙述,也可以对比连接池介绍```线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象;```1:网购商品秒杀多人同时抢购某件商品,只有部分人会成功,其他人失败;2:云盘文件上传和下载同时可以上传多个文件或下载多个文件,且有最大上传和下载文件的个数限制;3:12306网上购票系统等。

liuhm的博客 2022

gitlab远程子仓库配置SSH - 保姆级教程

在网上搜索了一些方法,但是不够详细,走了好多弯路,所以记录下配置SSH的详细过程吧。

是菠萝的博客 1万+

写给小白看的线程池,还有10道面试题

如何搞定20k的面试小抄为什么要用线程池呢?下面是一段创建线程并运行的代码:for(inti=0;i<100;i++){ newThread(()-&...

田维常 1917

保姆级教程:用OpenCV和MediaPipe在Python里实现实时手势识别(附完整代码)

本文提供了一份详细的Python教程,教你如何使用OpenCV和MediaPipe实现实时手势识别系统。从环境配置、手部关键点检测到手势分类算法,逐步讲解如何构建高精度手势识别应用,适用于智能家居控制、PPT操作等场景。教程包含完整代码示例和性能优化技巧,特别适合计算机视觉初学者和开发者实践。

weixin_28677005的博客 327

cMake编译 VS2026+opencv4.12.0+opencv_contrib-4.12.0

本文提供了OpenCV 4.12.0集成CUDA、cuDNN和ONNX Runtime的详细编译指南。主要步骤包括:准备Visual Studio 2026、CMake 4.2.0、CUDA 12.6和cuDNN 9.16.0;设置无空格和中文的路径结构;配置关键CMake变量(如开启CUDA支持、指定路径等);以及最终的编译安装过程。注意事项包括:版本一致性检查、cuDNN文件复制、国内用户需手动获取.cache文件等。文章还提供了常见问题解决方案,如通过设置CUDA_NVCC_FLAGS参数解决VS版本

weixin_46624734的博客 1384

线程池详解(建议收藏)

线程池(Thread Pool)是一种基于池化技术的多线程处理形式,用于管理线程的创建和生命周期,以及提供一个用于并行执行任务的线程队列。线程池的主要目的是减少在创建和销毁线程时所花费的开销和资源,提高程序性能,同时也提供了对并发执行任务的更好管理,例如控制线程数量。

wwwwwww31311的博客 1万+

定制PYNQ的overlay

一、用HLS生成一个定制IP(加速器)(1)首先打开vivado hls,本人的版本是2017.2,点击创建一个新工程。(2)设置工程名和路径,顶层函数设置为add,创建一个新的C++程序,名字叫做adder.cpp,不用在testbench中添加文件。选择板子的时候搜索xc7z020clg400-1,这是PYNQ的板子号,选择完成。             (3)在左侧的菜单栏里选择Sourc...

bramblewalls的博客 1万+

什么是线程池,线程池的概念、优点、缺点,如何使用线程池,最大线程池怎么定义?

线程池的优点包括重用线程、控制并发度、提供线程管理和监控等。通过适当地配置线程池的大小和任务队列的容量,可以充分利用系统资源,提高程序的性能和响应速度。同时,线程池可以避免线程创建和销毁的开销,减少了资源的浪费。线程池的基本概念是,在应用程序启动时创建一定数量的线程,并将它们保存在线程池中。当需要执行任务时,从线程池中获取一个空闲的线程,将任务分配给该线程执行。线程池的设计思想是为了避免频繁地创建和销毁线程的开销,以及控制并发执行的线程数量,从而提高系统的性能和资源利用率。

mcband的博客 4万+

RK3568 Android14 调试 RTL8211F 千兆以太网 (RGMII)

调试 RTL8211F 的核心在于:确认地址(看电阻贴片情况)和 搞定延时(配置 rgmii-id 或微调 delay 值)。一旦这两点对上了,RK3568 的千兆网络就能稳定运行。希望这篇结合原理图的实战记录能帮到你!

qq_33427070的博客 1649

文末含资料链接和视频讲解!YOLOv8集成CoordAtt注意力机制详细教程

本文详细介绍了如何在YOLOv8目标检测框架中集成CoordAtt注意力机制。首先解析了CoordAtt的工作原理,它通过分解式池化将位置信息嵌入到通道注意力中,相比传统注意力机制具有更好的空间信息保持能力。然后提供了PyTorch实现代码解析,包括自适应平均池化、Hard-Swish激活函数等关键实现细节。最后概述了YOLOv8架构,为后续集成CoordAtt提供基础。该教程适合具备深度学习基础的开发者,将理论与实践结合,帮助读者掌握这一目标检测优化技术。

FJN110的博客 266

线程池详解

线程池

qq_52463861的博客 5282

85-Halcon-- gen_cam_par_area_scan_division 函数功能(生成面阵相机镜头参数)

Halcon的gen_cam_par_area_scan_division算子用于生成面阵相机的镜头参数,支持除法畸变模型。该算子输出包含9个参数的元组,包括焦距(Focus)、畸变系数(Kappa)、像素尺寸(Sx,Sy)、主点坐标(Cx,Cy)和图像尺寸。文中详细解析了各参数含义、数学原理(包括畸变矫正公式和坐标转换),并提供了三个工业应用案例:高精度芯片尺寸测量、机器人焊接引导和大视野汽车表面检测。最后给出了完整的相机标定流程,涵盖参数生成、畸变校正和标定配置步骤,适用于工业视觉系统的精确标定需求。

weixin_45590420的博客 915

线程池的使用、工作原理和优势

线程池 , 在Java中,创建和销毁线程开销较大,为了避免线程过多而带来使用上的开销。 所以我们需要对线程进行统一管理及复用,这就是我们要说的线程池。

fumeidonga的博客 1453

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

JUC线程池和spring线程池

简介:目前常用的线程池有两种,一种是jdk自带的ThreadPoolExecutor来创建线程池,另一种是spring框架中的ThreadPoolTaskExecutor来创建线程池。 JDK自带的线程池 (1)线程池执行过程入下图: (2)常用的线程池 使用Executors创建线程池:这是jdk自带的创建线程池的方法。通过Exceutors创建线程池,常见的线程池有四种: Executors.newFixedThreadPool(int nThreads):固定长度的线程池...

qq_27661881的博客 1802

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

java多线程和线程池

目录 零、java线程理解 0.1 两种线程模型 0.1.1 用户级线程 ULT 0.1.2 内核级线程 KLT——JAVA虚拟机使用的线程模型(KLT) 0.2 java线程与系统内核线程 0.3 线程池的意义 0.4 线程 0.4.1线程五种状态 0.4.2 高并发下,线程池如何保证线程安全 0.4.3 多线程的使用场景 0.4.4 多线程的创建方式 0.4.4 多线程的停止 0.4.5控制多线程的运行顺序——join方法 一、线程池基本概念和使用示例 1.1 基本...

一直走,不要回头 8846

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

剖析 Tomcat 线程池与 JDK 线程池的区别和联系

Tomcat 线程池和 JDK 线程池都是在 Java 开发中非常有用的工具,用于处理不同类型的并发任务。本文将深入探讨 Tomcat 线程池与 JDK 线程池之间的区别和联系,以帮助开发人员更好地理解它们的工作原理和如何在自己的项目中使用它们。每个连接器都可以配置自己的线程池。:每个连接器可以有自己的线程池,这意味着在 Tomcat 中,可以有多个线程池在不同的连接器之间工作。:Tomcat 线程池的配置通常与 Tomcat 的连接器相关联,而 JDK 线程池是以编程方式或者使用配置类进行配置的。

学IT,找陈寒 9645

全面了解线程和线程池

本文介绍了线程、线程池等基本概念及其功能。线程是进程内的执行单元,共享进程资源。线程池通过复用线程提高效率,管理线程的创建、销毁和任务调度。此外,文章还详细描述了Java API中线程的生命周期状态及其与操作系统状态的对应关系,帮助理线程在不同环境下的行为,以及介绍了线程池的创建和使用。

emmmm的博客 760

局部线程池和全局线程池_Linux线程池

什么是池?池是一组资源的集合,这组资源在服务器启动之初就被创建并初始化开始处理客户请求的时候,如果它需要相关的资源,就可以直接从池中获取服务器处理完一个客户连接后,可以把相关的资源放回池中分享一个手写实现线程池的视频:150行代码写个线程池为什么要创建线程池?当有客户端连接时,创建耗时为:线程时间+处理时间+销毁线程时间(耗时T1+T2+T3)若需要大量的线程来完成任务,且完成任务的时间比较短,这...

weixin_34599904的博客 1575

局部线程池和全局线程池_Java线程池原理——自己手写线程池

所谓线程池,就是一个用来放线程的池子,里面存放着已经创建好的线程,当有任务提交的时候,池子里面的某个线程会执行这个任务,当任务结束后,线程又回到了池子里面等待下一个任务。当任务太多的时候,池子就要自动加水,创建更多的线程,但池子也是有容量的;当任务太少的时候,池子就要放掉一些线程,以免资源浪费。为什么需要线程池?因为线程是一个计算机的重要资源,创建,启动,销毁线程都是比较耗费计算机资源的,而且线程...

weixin_35281210的博客 1821

线程池和线程池的实现

线程池是指一种预先创建一组线程的机制,这些线程在应用程序启动时就已经创建好,等待执行任务。应有新的任务需要执行时,线程池会从线程集合中分配一个空闲线程来执行该任务,而不是每次都重新创建和销毁线程。-----池化思想线程复用:通过任务队列和条件变量,线程池中的线程可以复用,避免频繁创建和销毁线程。任务封装:使用封装任务,支持返回值获取。线程安全:通过互斥锁和条件变量确保任务队列的线程安全。异步结果:通过获取任务的异步执行结果。

逃离世界····· 898

Executors为啥线程池里面的线程和线程池都没释放

前言那么为啥线程池里面的线程和线程池都没释放呢。那么现在问题就转为线程对象是在什么时候gc。最后总结前言今天给大家分享一个线上问题引出的一次思考,过程比较长,但是挺有意思。今天上班把需求写完,出于学习(摸鱼)的心理上skywalking看看,突然发现我们的一个应用,应用内线程数超过900条,接近1000条,但是cpu并没有...

weixin_41400281的博客 452

多线程和线程池

文章目录前言一、关于线程和进程二、线程中常用API1.创建线程2.守护线程(daemon)3.线程终止(interrupt)4.线程执行顺序(join)5.volatile6.synchronized7.Lock8.线程交替打印9.消费者和生产模式 前言 1、线程不是由Java创建的,是有底层C++创建的。 2、线程是CPU调度的最小单元,进程是CPU分配资源的最小单元 3、资料整理参考自B站传智播客 一、关于线程和进程 1、概念:进程就是相当于一个应用程序,比如说是英雄联盟 而在联盟游戏,又有很多的线程,

weixin_45059879的博客 3467

Java中的线程和线程池

在Java中,线程是用于执行程序中独立任务的执行单元。它允许多个任务同时执行,从而提高程序的并发性。线程池是线程的管理机制,它维护着一个线程集合,可以重复利用这些线程来执行多个任务。

九离的博客 1250
上一篇: java中数组
下一篇: Retrofit提交参数
android_xiaogang
博客等级 码龄12年 89粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值