多线程学习
并发:交替运行
并行:一起运行
多线程实现方式
继承Thread类
①自己定义一个类继承Thread
public class MyThread extends Thread{public void run(){}}
②重写run方法
public class MyThread extends Thread{public void run(){"重写的内容"}}
③创建子类对象,并启动线程
MyThread t1 = new MyThread();
t1.setName("线程1的名字");
t1.start("开始运行线程1");
实现Runnable接口
①自己定义一个类实现Runnable接口
public class MyRun implements Runnable{public void run(){}
}
②重写里面的run方法
public class MyRun implements Runnable{public void run(){"重写的代码"}
}
注意:在重写run的过程中是不能调用getName这个方法的,因为使用的是自己创建的类,如果要使用的话,可以用Thread t = Thread.currentThread();就相当于返回的是相应线程的对象
③创建自己的类的对象
Myrun mr = new Myrun();
④创建一个Thread类的对象
Thread t1 = new Thread(mr);
利用Callable接口和Future接口(可以获取到多线程运行的结果)
①创建一个类MyCallable实现Callable接口
public class MyCallable implements Callable<V>{public V call(){return V;}
}
②重写call(有返回值)
③创建MyCallable的对象(表示多线程要执行的任务)
MyCallable mc = new MyCallable();
④创建FutureTask的对象(作用管理多线程运行的结果)
//管理Callanle
FutureTask<V> ft = new FutureTask<>(mc);
⑤创建Thread类的对象,并启动
Thread t1 = new Thread(ft);
t1.start();
V result = ft.get();//获取结果
常见的成员方法
setName()
注意:
- 如果没有给线程设置名字,线程也是有默认名字的
- 如果我们要给线程设置名字,可以用set方法进行设置,也可以用构造方法设置
currentsThread()
- 当JVM虚拟机启动之后,会自动的启动多个线程,其中有一条叫做main线程,它的作用就是去调用main方法,并执行里面的代码
sleep()
- 哪条线程执行到这个方法,那么那条线程就要在这停留相应的时间
- 方法的参数:就表示这个停留的时间,单位毫秒
- 当时间到了之后,线程就会自动醒来,继续执行下面的代码
setPriority(); -----设置优先级
线程的调度(抢占CPU)
抢占式调度:随机性
非抢占式调度
setDeamon() ----- 设置守护线程
当其他线程都结束之后,守护线程也随之结束
例子:如果在聊条过程中,一边发送信息,一边发送文件,当关闭了发送信息的窗口的时候,那么文件也没必要发送,就结束发送文件这个线程
yield() ------ 礼让逻辑
作用,尽可能让各个线程执行的次数均匀
join() ------- 加入线程
线程的生命周期
线程的安全
同步代码块
容易出现问题的原因:在线程执行的时候,有随机性
解决:如果能把线程操作共享数据的代码锁起来,只让一条线程执行,这条线程执行完之后才能让下一条线程执行代码
关键字:synchronized(锁对象){操作共享的数据}
public class MyThread extends Thread{//static保证锁对象是唯一的
//创建一个任意的锁对象
static Object obj = new Object();synchronized(obj){操作代码}
}
特点:
- 锁默认打开,有一个线程进去了,锁自动关闭
- 里面的代码全部执行完毕,线程出来,锁自动打开
同步方法
特点:
- 同步方法是锁定方法里面的所有代码
- 锁对象不能自己指定
//Ctrl + Alt + m 将代码块抽取成方法
Lock锁
可以手动上锁和释放锁
lock();上锁
unlock();释放锁
死锁(错误)
不要让俩个锁嵌套使用
生产者和消费者(等待唤醒机制)
消费者等待
首先是消费者抢到了CPU的执行权
消费者
- 判断是否生产者生产了数据
- 如果没有就等待(wait)
生产者
- 生产数据
- 制作数据
- 叫醒消费者消费数据(notify)
生产者等待
俩次都是生产者抢到了CPU的执行权
生产者
- 判断是否现在是否生成了数据
- 有:等待
- 没有:生产数据
- 把数据放着
- 叫消费者消费数据
消费者
- 判断是否有数据可以消费
- 没有就等待
- 有就开始消费
- 没有就叫生产者开始生产
常用方法
解决方案
阻塞队列方式实现
生产者和消费者一定要使用一个阻塞队列
take()----获取
put()-----放入
注意:这俩个方法的底层都是上了锁的,不用再格外的去加锁
代码表示
厨师(生产者)
package com.FC;import java.util.concurrent.ArrayBlockingQueue;public class Cook extends Thread{ArrayBlockingQueue<String> queue;public Cook(ArrayBlockingQueue<String> queue){this.queue = queue;}public void run(){while(true){try {queue.put("面条");System.out.println("厨师放了一碗面条");} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
吃货(消费者)
package com.FC;import java.util.concurrent.ArrayBlockingQueue;public class Foodie extends Thread{ArrayBlockingQueue<String> queue;public Foodie(ArrayBlockingQueue<String> queue){this.queue = queue;}public void run(){while(true){try {String food = queue.take();System.out.println("我吃了一碗面条");} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
运行代码
package com.FC;import java.util.concurrent.ArrayBlockingQueue;public class ThreadDemo {public static void main(String[] args) {//创建阻塞队列的对象ArrayBlockingQueue<String > queue = new ArrayBlockingQueue<>(1);//创建线程Cook c = new Cook(queue);Foodie f = new Foodie(queue);//给线程设置名字c.setName("厨师");f.setName("吃货");//开启线程c.start();f.start();}
}
线程的状态
线程池
当有任务出现的时候,如果线程池里面为空,就创建一个新的线程,用于执行这个任务,执行完之后,把这个线程放到线程池里面,当下一个任务出现的时候,就不用创建新的线程了,直接从线程池里面拿现成的线程执行任务
用工具类实现
1.创建一个池子
//没有上限的线程池
public static ExecutorService newCachedThreadPool();
//有上限的线程池
public static ExecutorService newFixedThreadPool(int nThreads);
ExecutorService pool1 = Executors.newCachedThreadPool();
2.提交任务
pool1.submit(new MyRunnable());
3.所有的任务全部执行完毕之后,关闭线程池
pool1.shutdown();
自定义实现
自定义线程池中有核心线程和临时线程(都有一定的数量),当有很多任务要进行的时候,核心线程先进行一部分,然后一些任务排在队列里面(有一定的长度),当队列排满了之后,才会创建临时线程。
如果核心线程加上临时线程再加上队伍的长度都小于要执行的任务,那么默认会采用抛弃策略
ThreadPoolExecutor pool = new ThreadPoolExecutor(3,//核心线程数,不能小于06,//最大线程数,不能小于0,且要大于等于核心线程数60,//空闲线程最大存活时间TimeUnit.SECONDS,//时间单位new ArrayBlockingQueue<>(3),//任务队列Executors.defaultThreadFactory(),//创建线程工厂new ThreadPoolExecutor.AbortPolicy()//任务的拒绝策略);
其他
获取电脑的可用的处理器数目
int count = Runtime.getRuntime().availableProcessors();
线程池大小的定夺
相关文章:
多线程学习
并发:交替运行 并行:一起运行 多线程实现方式 继承Thread类 ①自己定义一个类继承Thread public class MyThread extends Thread{public void run(){}} ②重写run方法 public class MyThread extends Thread{public void run(){"重写的内容&…...
软件测试/测试开发丨ChatGPT在测试计划中的应用策略
点此获取更多相关资料 简介 测试计划是指描述了要进行的测试活动的范围、方法、资源和进度的文档。它主要包括测试项、被测特性、测试任务和风险控制等。 所以在使用ChatGPT输出结果之前,我们需要先将文档的内容框架梳理好,以及将内容范围划定好&…...
链表oj3(Leetcode)——相交链表;环形链表
一,相交链表 相交链表(Leetcode) 1.1分析 看到这个我们首先想到的就是一个一个比较他们的值有相等的就是交点,但是如果a1和b2的值就相等呢?所以这个思路不行,第二种就是依次比较链表,但是这…...
nginx反向代理
nginx反向代理8.反向代理8.1 实现http反向代理8.1.1 反向代理配置参数8.1.2 反向代理单台web服务器8.1.2.1 端口号后加"/"8.1.2.2 端口号后不加"/" 8.1.3指定location 实现反向代理,动静分离8.1.4 反向代理实例:缓存功能8.1.4.1 举例 8.1.5 实现…...
基于eBPF的安卓逆向辅助工具——stackplz
前言 stackplz是一款基于eBPF技术实现的追踪工具,目的是辅助安卓native逆向,仅支持64位进程,主要功能如下: hardware breakpoint 基于pref_event实现的硬件断点功能,在断点处可读取寄存器信息,不会被用户…...
十大排序——4.堆排序
前面我们讲了堆,现在我们来看一下队排序。 堆排序的步骤: 首先将一个无序数组建立成一个大顶堆然后,将堆顶的元素和堆低的元素进行交换(即将最大的元素交换的到堆底),缩小并下潜调整堆重复上一步…...
独辟蹊径”之动态切换进程代理IP
前言 项目中遇到这样一个需求,需要动态切换指定进程Sockets5代理IP,目前了解到可通过编写驱动拦截或者劫持LSP实现,LSP劫持不太稳定,驱动无疑是相对较好的解决方案,奈何水平不足便有了这"蹊径"。 初步尝试…...
redis漏洞修复:(CNVD-2019-21763)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、漏洞内容二、镜像准备1.确认镜像版本2.下载镜像 三、配置文件准备1.获取配置文件2.修改配置文件 四、启动redis容器五、修改iptables文件总结 前言 漏扫发…...
手刻 Deep Learning -第壹章-PyTorch入门教学-基础概念与再探线性回归
一、前言 本章会需要 微分、线性回归与矩阵的基本观念 这次我们要来做 PyTorch 的简单教学,我们先从简单的计算与自动导数( auto grad / 微分 )开始,使用优化器与误差计算,然后使用 PyTorch 做线性回归,还有…...
深入学习 Redis - 如何使用 Redis 作缓存?缓存更新策略?使用需要注意哪些问题(工作/重点)
目录 一、Redis 作为缓存 1.1、缓存的基本概念 1.1.1、理解 1.1.2、缓存存什么样的数据?二八定律 1.2、如何使用 redis 作为缓存 1.3、缓存更新策略(redis 内存淘汰机制 / 重点) 1.3.1、定期生成 1.3.2、实时生成 内存淘汰策略&#…...
好用的软件测试框架有哪些?测试框架的作用是什么?
软件测试框架是现代软件开发过程中至关重要的工具,它可以帮助开发团队更加高效地进行测试和验证工作,从而大大提高软件质量和用户体验。 一、好用的软件测试框架 1. Selenium:作为一种开源的自动化测试框架,Selenium具有功能强大…...
PAT 1035 插入与归并
PAT 1035 插入与归并 题目描述思路讲解代码展示 题目描述 思路讲解 分析:先将i指向中间序列中满足从左到右是从小到大顺序的最后一个下标,再将j指向从i1开始,第一个不满足a[j] b[j]的下标,如果j顺利到达了下标n,说明…...
K-means 聚类算法学习笔记
K-means 聚类算法 是一种无监督学习算法,用来将 n n n 个样本点分成 k k k 类,使得整个数据集的误差平方和 S S E SSE SSE 最小。在本例中,样本点是指平面直角坐标系上的点,聚类中心也是平面直角坐标系上的点,而每个…...
API文档搜索引擎
导航小助手 一、认识搜索引擎 二、项目目标 三、模块划分 四、创建项目 五、关于分词 六、实现索引模块 6.1 实现 Parser类 6.2 实现 Index类 6.2.1 创建 Index类 6.2.2 创建DocInfo类 6.2.3 创建 Weight类 6.2.4 实现 getDocInfo 和 getInverted方法 6.2.5 实现 …...
文案内容千篇一律,软文推广如何加深用户印象
随着互联网技术的发展,企业营销的方式逐渐转向软文推广,但是现在软文推广的内容同质化越来越严重,企业应该如何让自己的软文推广保持差异性,在用户心中留下独特的印象呢?下面就让媒介盒子告诉你。 一、 找出产品独特卖…...
十二、流程控制-循环
流程控制-循环 1.while循环语句★2.do...while语句★3.for循环语句 —————————————————————————————————————————————————— 1.while循环语句★ while语句也称条件判断语句,它的循环方式是利用一个条件来控制是否…...
五、回溯(trackback)
文章目录 一、算法定义二、经典例题(一)排列1.[46.全排列](https://leetcode.cn/problems/permutations/description/)(1)思路(2)代码(3)复杂度分析 2.[LCR 083. 全排列](https://le…...
什么是分布式锁?他解决了什么样的问题?
相信对于朋友们来说,锁这个东西已经非常熟悉了,在说分布式锁之前,我们来聊聊单体应用时候的本地锁,这个锁很多小伙伴都会用 ✔本地锁 我们在开发单体应用的时候,为了保证多个线程并发访问公共资源的时候,…...
Ubuntu 12.04增加右键命令:在终端中打开增加打开文件
Ubuntu 12.04增加右键命令:在终端中打开 软件中心:搜索nautilus-open-terminal安装 用快捷键CtrlT打开命令行输入: sudo apt-get install nautilus-open-terminal 重新加载文件管理器 nautilus -q 或注销再登录即要使用...
Centos 7 访问局域网windows共享文件夹
Refer: centos7 访问windows系统的共享文件夹_centos访问windows共享_三希的博客-CSDN博客 一、在CentOS中配置CIFS网络存储服务 CIFS(Common Internet File System)是一种在网络上共享文件的协议,也称为SMB(Server Message Blo…...
GDB的TUI模式(文本界面)
2023年9月22日,周五晚上 今晚在看GDB的官方文档时,发现GDB居然有文本界面模式 TUI (Debugging with GDB) (sourceware.org) GDB开启TUI的条件 GDB的文本界面的开启条件是:操作系统有适当版本的curses库 The TUI mode is supported only on…...
深入了解Python和OpenCV:图像的卡通风格化
前言 当今数字时代,图像处理和美化已经变得非常普遍。从社交媒体到个人博客,人们都渴望分享独特且引人注目的图片。本文将介绍如何使用Python编程语言和OpenCV库创建令人印象深刻的卡通风格图像。卡通风格的图像具有艺术性和创意,它们可以用…...
【算法挨揍日记】day06——1004. 最大连续1的个数 III、1658. 将 x 减到 0 的最小操作数
1004. 最大连续1的个数 III 1004. 最大连续1的个数 III 题目描述: 给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。 解题思路: 首先题目要我们求出的最多翻转k个0后&#x…...
华为云HECS安装docker
1、运行安装指令 yum install docker都选择y,直到安装成功 2、查看是否安装成功 运行版本查看指令,显示docker版本,证明安装成功 docker --version 或者 docker -v 3、启用并运行docker 3.1启用docker 指令 systemctl enable docker …...
力扣669 补9.16
最近大三上四天有早八,真的是受不了了啊,欧嗨呦,早上困如狗,然后,下午困如狗,然后晚上困如狗,尤其我最近在晚上7点到10点这个时间段看力扣,看得我昏昏欲睡,不自觉就睡了1…...
2023-9-22 没有上司的舞会
题目链接:没有上司的舞会 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 6010;int n; int happy[N]; int h[N], e[N], ne[N], idx; bool has_father[N];// 两个状态,选该节点或不选该…...
【HDFS】cachingStrategy的设置
org.apache.hadoop.hdfs.client.impl.BlockReaderFactory#getRemoteBlockReader: private BlockReader getRemoteBlockReader(Peer peer) throws IOException {int networkDistance = clientContext.getNetworkDistance(datanode);return BlockReaderRemote...
性能测试 —— 性能测试常见的测试指标 !
一、什么是性能测试 先看下百度百科对它的定义,性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。 我们可以认为性能测试是:通过在测试环境下对系统或构件的性能进行探测,用以验证在生产环…...
【学习草稿】背包问题
一、01背包问题 图解详细解析 (转载) https://blog.csdn.net/qq_37767455/article/details/99086678 :Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物…...
doxygen c++ 语法
c基本语法模板 以 /*! 开头, */ 结尾 /*!\关键字1\关键字2 */1 文件头部信息 /*! \file ClassA.h* \brief 文件说明 定义了类fatherA* \details This class is used to demonstrate a number of section commands.* \author John Doe* \author Jan Doe* \v…...
购物网站开发 webstorm/网页设计与网站开发
之前我们讲解了Git在本地版本库中的基本操作,这些操作和Linux系统中的操作基本相同。之后,在上一篇中,我们记述了如何获得SSH密钥,以及如何与Github连接的问题。在这些准备工作做好了之后,我们尝试使用Github。 本文使…...
专业网站建设推荐/seo网站排名优化服务
对于搜索引擎, 在索引量和搜索量大到一定程度的时候, 索引更新的效率会逐渐降低, 服务器的压力逐渐升高, 因此基本上整个搜索引擎的利用率可以说是越来越低了, 并且随着海量数据存储带来的困难, 设计一个良好的分布式搜索引擎将是一个搜索引擎能否面相未来发展的关键因素了. 那…...
网站注册管理策划方案/艾滋病阻断药
一、连接查询[连表查询、多表查询]当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回mysql支持三种类型的连接查询,分别为:内连接查询(inner join)查询的结果为两个表匹配到的数据使用内连接&am…...
苏州网络网站建设/seo内容优化方法
大家好,我偶然发现了一个很酷的jQuery插件,称为innerfade。 基本上,它旋转存储在列表中的元素,这些元素可能是文本,图像,链接等。 可以与任何容器标签(例如divs或uls),所…...
口腔医院网站做优化/关键词分析
随着人工智能的发展,人脸识别技术在各个领域的场景应用中日益丰富,在多个场景可以看到人脸识别系统的应用落地,在社区、企业、工地、安防等方面。而现在随着各地智慧校园的建设,有些学校逐步引入人脸识别技术,通过校园…...
免费微网站系统源码/爱站网长尾关键词搜索
早晨起床时间:6:30 晚上休息时间:12:49 全天处理事件:1.上班。 处事经验总结:暂无。 人生感悟:暂无。 其它:今天我们部门聚餐,又学到很多东西。希望自己在今年能够克服自身的一些缺点࿰…...