多线程相关

一、Thread

1.通过继承Thread类,重写run方法,调用start开启线程
2.直接new一个Thread类对象,传入一个Runnable对象,调用start开启线程

public class MyThread extends Thread
{@Overridepublic void run() {System.out.println("PS--test Mythread");}
}MyThread myThread = new MyThread();
myThread.start();
//测试以来Runnable接口
new Thread(new MyRunnable()).start();

二、Runnable

1.通过继承Runnable接口,重写run方法,传入Thread方法中调用start开启线程
2.直接new一个Runnable接口对象,传入Thread方法中调用start开启线程

public class MyThread extends Thread
{@Overridepublic void run() {System.out.println("PS--test Mythread");}
}public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("PS--test MyRunnable");}
}//测试依赖Thread类
MyThread myThread = new MyThread();
myThread.start();
//测试以来Runnable接口
new Thread(new MyRunnable()).start();
//直接使用Runnable
new Thread(() -> System.out.println("PS--test Runnable interface")).start();
/**
*         同上:
*         new Thread(new Runnable() {
*             @Override
*             public void run() {
*                 System.out.println("PS--test Runnable interface");
*             }
*         }).start();
*/

三、线程池

1.简易方法创建

/*** 可缓存无界线程池测试* 当线程池中的线程空闲时间超过60s则会自动回收该线程,核心线程数为0* 当任务超过线程池的线程数则创建新线程。线程池的大小上限为Integer.MAX_VALUE,* 可看做是无限大。*/
ExecutorService threadPoolExecutor1= Executors.newCachedThreadPool();/*** 创建只有一个线程的线程池测试* 该方法无参数,所有任务都保存队列LinkedBlockingQueue中,核心线程数为1,线程空闲时间为0* 等待唯一的单线程来执行任务,并保证所有任务按照指定顺序(FIFO或优先级)执行*/
ExecutorService threadPoolExecutor2= Executors.newSingleThreadExecutor();/*** 创建固定线程数量的线程池测试* 创建一个固定大小的线程池,该方法可指定线程池的固定大小,对于超出的线程会在LinkedBlockingQueue队列中等待* 核心线程数可以指定,线程空闲时间为0*/
ExecutorService threadPoolExecutor3= Executors.newFixedThreadPool(5);/**
* 定时执行任务的线程池
* 创建指定核心线程数,最大线程数是Integer.MAX_VALUE
*/
ExecutorService threadPoolExecutor4= Executors.newScheduledThreadPool(3);
// 创建一个大小为 3 的定时执行任务的线程池
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(3);
// 延迟 2 秒后执行任务
executor.schedule(() -> {System.out.println("Task 1 executed after 1 second");
}, 2, TimeUnit.SECONDS);
// 延迟 2 秒后开始执行任务,之后每隔 3 秒执行一次
executor.scheduleAtFixedRate(() -> {System.out.println("Task 2 executed at fixed rate of 3 seconds");
}, 2, 3, TimeUnit.SECONDS);
// 延迟 2 秒后开始执行任务,之后每隔 3 秒执行一次
executor.scheduleWithFixedDelay(() -> {System.out.println("Task 3 executed after 3 seconds on last task finished");
}, 2, 2, TimeUnit.SECONDS);

2.ThreadPoolEwector创建

线程池的七大参数:
1.核心线程数–corePoolSize
2.最大线程数–maximumPoolSize
当前线程数达到corePoolSize后,如果继续有任务被提交到线程池,会将任务缓存到工作队列中。如果队列也已满,则会去创建一个新线程*来出来这个处理,此时可创建的新线程数量由maximunPoolSize指定。
3.线程存活时间–keepAliveTime
一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在keepAliveTime时间后,这个空闲线程会被销毁
4.线程存活时间单位
5.工作队列–workQueue
新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:
①ArrayBlockingQueue
基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。
②LinkedBlockingQueue
基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而基本不会去创建新线程直到maxPoolSize(很难达到Interger.MAX这个数),因此使用该工作队列时,参数maxPoolSize其实是不起作用的。
③SynchronousQueue
一个不缓存任务的阻塞队列,新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。
④PriorityBlockingQueue
具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
6.线程工厂–threadFactory
默认工厂 Executors.defaultThreadFactory()
7.拒接策略–handler
当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来则只需拒绝策略
①CallerRunsPolicy
在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
②AbortPolicy
直接丢弃任务,并抛出RejectedExecutionException异常。
③DiscardPolicy
直接丢弃任务,什么都不做。
④DiscardOldestPolicy
抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor (3,8,50,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());
for(int i=0; i<50; i++) {threadPoolExecutor.execute(new MyRunnable());
}

提交线程任务:
execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否;
submit()方法用于提交需要返回值的任务。线程池会返回一个 Future 类型的对象,通过这个 Future 对象可以判断任务是否执行成功 ,并且可以通过 Future 的 get()方法来获取返回值,get()方法会阻塞当前线程直到任务完成,而使用 get(long timeout,TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。
关闭线程池:
shutdown()关闭线程池,线程池的状态变为 SHUTDOWN。线程池不再接受新任务了,但是队列里的任务得执行完毕。
shutdownNow()关闭线程池,线程的状态变为 STOP。线程池会终止当前正在运行的任务,并停止处理排队的任务并返回正在等待执行的 List。

四、异步代码顺序执行

多个线程异步执行时使多个线程按照先后顺序同步执行。

1.通过join方式

val thread1 = Thread {Log.d("111111", "111111")
}
val thread2 = Thread {Log.d("111111", "222222")
}
val thread3 = Thread {Log.d("111111", "333333")
}
thread1.start()
thread1.join()
thread2.start()
thread2.join()
thread3.start()
thread3.join()

2.通过线程池

val thread1 = Thread {Log.d("111111", "111111")
}
val thread2 = Thread {Log.d("111111", "222222")
}
val thread3 = Thread {Log.d("111111", "333333")
}
val executor = Executors.newSingleThreadExecutor()//创建单个线程的线程池
executor.submit(thread1)
executor.submit(thread2)
executor.submit(thread3)
executor.shutdown()//关闭

五、android中的Handler

1. handler.sendMessage

传递Message信息

//PlanEvent EventListener基本定义,此处不再赘述object EventHandler
{private const val TAG = "EventHandler"//子线程Handlerprivate val eventListeners = listOf<EventListener>().toMutableList()private val workThread: HandlerThread = HandlerThread("EventHandler thread")private var innerEventHandler = object : Handler(workThread.looper) {override fun handleMessage(msg: Message) {super.handleMessage(msg)val bundleData: Bundle = msg.dataval originalText = bundleData.getString("originalText")val source = bundleData.getString("source")val planEvent = PlanEvent(originalText,source!!)synchronized(eventListeners) {eventListeners.forEach { it.onEventData(planEvent) }}Log.d(TAG, "event data: $planEvent")}}fun sendMessage(msg: Message) {innerEventHandler.sendMessage(msg)}fun addEventListener(listener: EventListener) {synchronized(eventListeners) {eventListeners.add(listener)}}fun removeEventListener(listener: EventListener) {synchronized(eventListeners) {eventListeners.remove(listener)}}
}

2.handler.post

post(Runnable runnable)方法接受一个Runnable对象,且runnable的run方法中的操作可在主线程更新,例如执行ui操作
post方法不用调用start

val handler = Handler()
mRunnable = object:Runnable {//可转化为Lambda表达式override fun run() {mChangeValue++mListener?.onChanged(mChangeValue)handler.postDelayed(mRunnable, 2000)//实现一直定时功能}
}
handler.postDelayed(mRunable,2000)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10845.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

《PyTorch深度学习快速入门教程》学习笔记(第20周)

目录 摘要 Abstract 1. 池化层原理 2. 二维池化层 3. 二维最大池化 4. 填充、步幅与多个通道 5. 平均池化层 6. 理论总结 7. 池化层处理数据 8. 池化层处理图片 摘要 本周报的目的在于汇报《PyTorch深度学习快速入门教程》课程第六周的学习成果&#xff0c;主要聚焦于…

C# 实现对指定句柄的窗口进行键盘输入的实现

在C#中实现对指定句柄的窗口进行键盘操作&#xff0c;可以通过多种方式来实现。以下是一篇详细的指南&#xff0c;介绍如何在C#中实现这一功能。 1. 使用Windows API函数 在C#中&#xff0c;我们可以通过P/Invoke调用Windows API来实现对指定窗口的键盘操作。以下是一些关键的…

c语言简单编程练习10

1、typedef和#define的区别 在用作数据类型替换时的区别&#xff1a; #include <stdio.h> #include <unistd.h>typedef char * A; //typedef需要&#xff1b; #define B char *int main(int argc, char *argv[]) {A a,b;B c,d;printf("a_size%ld\n"…

题目讲解15 合并两个排序的链表

原题链接&#xff1a; 合并两个排序的链表_牛客题霸_牛客网 思路分析&#xff1a; 第一步&#xff1a;写一个链表尾插数据的方法。 typedef struct ListNode ListNode;//申请结点 ListNode* BuyNode(int x) {ListNode* node (ListNode*)malloc(sizeof(ListNode));node->…

【freertos】FreeRTOS任务管理

FreeRTOS任务管理 一、任务的创建和删除1、函数xTaskCreate2、函数xTaskCreateStatic3、函数xTaskCreateRestricted4、函数vTaskDelete 二、任务的挂起和恢复1、函数vTaskSuspend2、函数vTaskResume3、函数vTaskResumeFromISR4、函数vTaskSuspendAll5、函数xTaskResumeAll 三、…

FreeRTOS 20:互斥量(互斥信号量)操作

互斥信号量其实就是一个拥有优先级继承的二值信号量&#xff0c;在同步的应用中&#xff08;任务与任务或中断与任务之间的同步&#xff09;二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中。在互斥访问中互斥信号量相当于一把钥匙&#xff0c; 当任务想要访问共…

MongoDB笔记03-MongoDB索引

文章目录 一、前言1.1 概述1.2 MongoDB索引使用B-Tree还是BTree&#xff1f;1.3 B 树和 B 树的对比1.4 总结 二、索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引 三、索引的管理操作3.1 索引的查看3.2 索引的创建3.2.1 单字段索引3.2.2 复合索引 3.3 索引的移除3.3.1 指定索…

肿瘤治疗评价指标太多?一文帮你梳理清楚!|个人观点·24-11-09

小罗碎碎念 如何延长癌症患者存活时间、提高生存质量、减轻肿瘤带来的痛苦&#xff0c;是评价抗癌药物的重要标准&#xff0c;而把这些标准落在数据上就诞生了各项“评价指标”。 在肿瘤治疗领域&#xff0c;有OS、PFS、RFS、TTP、TTF、ORR、DCR、DDC等各项评价指标。对于大部…

保研考研机试攻略:python笔记(3)

&#x1f428;&#x1f428;&#x1f428;11sort 与 sorted 区别 sort 是应用在 list 上的方法&#xff0c;sorted 可以对所有可迭代的对象进行排序操作。 list 的 sort 方法返回的是对已经存在的列表进行操作&#xff0c; 无返回值&#xff0c;而内建函数 sorted 方法返回的…

Linux之自定义shell和C标准库函数

自定义shell和C标准库函数 一.自定义xshell1.1main函数主体1.2获取用户信息以及命令串1.3判断命令串是否为空串1.4判断是否为重定向1.5分割命令串1.6判断是否为内建命令1.7执行命令 二.自定义C标准库函数2.1mystdio.h2.2mystdio.c2.3main.c 一.自定义xshell 1.1main函数主体 1…

TeamTalk知识点梳理一(单聊)

文章目录 db_proxy_serverdb_proxy_server reactor响应处理流程连接池redis连接池MySQL连接池 单聊消息消息如何封装&#xff1f;如何保证对端完整解析一帧消息&#xff1f;协议格式&#xff1f;单聊消息流转流程消息序号&#xff08;msg_id &#xff09;为什么使用redis生成&a…

带跳转功能的电子产品目录如何制作?

​在数字化时代&#xff0c;电子产品已成为我们生活和工作中不可或缺的伙伴。为了方便用户快速查找所需产品&#xff0c;带跳转功能的电子产品目录应运而生。本文将详细介绍如何制作一个高效便捷的带跳转功能电子产品目录&#xff0c;让用户轻松实现产品查找、筛选和购买。 1.要…

从0开始linux(26)——动静态库

欢迎来到博主的专栏&#xff1a;从0开始linux 博主ID&#xff1a;代码小豪 文章目录 如何写一个静态库动态库动静态链接 c/c程序形成可执行程序&#xff0c;需要经过三个步骤&#xff0c;编译、汇编、链接三个步骤&#xff0c;我们之前做链接时&#xff0c;使用的方法是将头文件…

hexo 搭建个人博客网站

hexo搭建个人博客 文章目录 hexo搭建个人博客摘要搭建网站的前置工具WebStormHexo Hexo配置初始化本地运行 主题更改安装butterfly主题 正式上线GitHub Pages配置新建仓库SSH密钥配置 将hexo部署到GitHub 个性化设置后续网站更新内容分类和标签设置分类&#xff08;categories&…

BLDC基础知识复习【二】

如果采用20毫欧的电流采样电阻&#xff0c;10A的电流计算出来时0.2V&#xff0c;这个显然还是太小了&#xff0c;需要运放放大并且加上偏置&#xff1a; 6组换向程序&#xff1a; 最核心的控制逻辑在这里&#xff1a;在main.c里面对PWM占空比进行设置&#xff0c;通过一个指针在…

1130 - Host ‘10.0.0.1‘ is not allowed to connect to this MySQL server

1130 - Host 10.0.0.1 is not allowed to connect to this MySQL server 一、1130 - Host 10.0.0.1 is not allowed to connect to this MySQL server二、1130 - Host 10.0.0.1 is not allowed to connect to this MariaDB serverendl 一、1130 - Host ‘10.0.0.1’ is not all…

构建智慧城市:数字孪生技术的发展之路

基于数字孪生的智慧城市发展是一种革命性的城市转型模式&#xff0c;旨在将物理世界与数字世界融合&#xff0c;在数字平台上建立城市的虚拟映像&#xff0c;从而实现对城市运行状态、资源利用、环境影响等方面的综合管理和优化。这种发展模式将数字技术深度融入城市规划、建设…

金融行业信息流投放方法论及金融客户投放案例

失血2024&#xff0c;金融行业进入“极寒”&#xff0c;广告投放也不例外。 受金融政策管控&#xff0c;在渠道投放受限也颇多&#xff0c;创意文案及素材上审核异常严格&#xff0c;整体投放成本高…… 金融理财信息流广告投放&#xff0c;如带着“镣铐”跳舞&#xff0c;束…

Unity-Yaml-Dot-Net诗歌篇-如何像雷总学习写代码像诗歌-MVC 框架,+注入Inject +状态机生命周期

我们是否可以像雷总一样 大家都说他的代码&#xff0c;像诗一样优雅 一个MVC 框架&#xff0c;加注入 &#xff08;以下内容其实和雷总没什么关系&#xff0c;也和雷总当年代码毫无关系&#xff0c;不过先“阅读理解”一下&#xff09; 雷总-写的代码像似一个优雅??!!^^ R…

安卓好软-----电脑端查看apk全部信息的工具 查看包名 名称以及权限等等

有时候从网络下载的应用很多是英文。时间久了会忘记到底是什么apk应用。这款工具可以方便的查看apk应用的名称 包名以及各种权限 图标 大小版本号等等。方便用户随时查看 APK Helper能够详细地获得安装包名、软件名称、APK证书、真实版本号、要求的手机版本、系统权限、以及证书…