Java学习笔记(23)

多线程

并发

并行

多线程实现方式

1.继承Thread类

自己创建一个类extends thread类

Start方法开启线程,自动执行重写之后的run方法

2.实现runable接口

自己创建一个类implements runnable

Myrun不能直接使用getname方法,因为这个方法是thread类的方法

所以需要得到当前线程的thread对象,再用getname方法

3.用callable接口和future接口方法

抽象方法run没有返回值,获取不了运行结果

实现callable接口

重写call方法

Future接口不能直接用,要用他的实现类futuretask管理线程运行结果

Thread的方法

Getname

没有起名,有默认名字:Thread-0,Thread-1.。。

Setname

设置线程名字,可以用set,也可以用构造方法,但是构造方法不能继承,要自己重新写个构造方法,通过super继承父类的构造方法

CurrentThread

Sleep 静态方法 用Thread.sleep调用

抢占式调度

随机

优先级最高10,最小1,默认5

Setpriority(int)

Getpriority

守护线程

SetDaemon(true)

非守护和守护默认没有优先级之分

非守护结束,守护慢慢就也会结束

出让线程

Thread.yield()

让结果每一个线程尽可能均匀运行

插入线程

线程的生命周期

有执行资格:有资格去抢CPU的执行权

没有执行权:还没抢到执行权,不能执行代码

线程安全

Ticket要用static修饰,这样所有这个类的对象就可以共享ticket

为什么会出现这个问题?

执行代码时,线程随时都会被其他线程抢夺执行权

如何解决?

同步代码块

让一个线程执行完完整的一次同步代码块里的代码,才可以重新抢夺执行权

Synchronized(锁对象){}

锁对象:是任意的,但是一定是唯一的,前面用static修饰

锁对象可以是本类的字节码文件

同步方法

如果想把一个方法里面所有的代码都锁起来,就不需要同步代码块

直接将synchronized加在方法上

用runable的时候,由于只需要创建一次,所以里面的ticket就可以不用static修饰

Stringbuffer用于多线程环境,里面的方法和stringbuilder一样的

Lock锁

是一个接口,创建对象要用实现类reentrantlock

以上代码可能出现的问题:

  1. 如果lock没有用static修饰

则会所有的线程都会创建一个lock,重复ticket,超出范围的问题又会出现,所以要加static修饰,即所有线程共享一个lock,就能解决

        2.程序不停止?

没有执行lock.unlock()方法,有线程一直停留在lock.lock()方法,所以程序没有停止

如何避免?

把unlock写到finally中,保证unlock一定会执行

死锁

不要让两个锁嵌套起来写,这样程序就运行不下去

生产者和消费者

等待唤醒机制

生产者:生产数据

消费者:消费数据

消费者等待

生产者等待

完整机制

方法

Wait

一般用notifyall

这几个方法要通过锁对象来进行调用

重写run方法的套路

Desk

Foodie

Cookie

测试类

第二种实现方式:阻塞队列方式

  1. 数组,有界
  2. 链表,无界

生产者和消费者要使用同一个阻塞队列

不需要在写锁对象,因为put和take方法的底层就已经有锁了

Take有返回值,类型和put进去的数据一样

线程的状态

Java没有定义运行状态,只有剩下的六种状态

为什么没有?

因为线程抢到CPU的执行权之后,当前线程就会交给操作系统管理,虚拟机就不会再管这个线程了

package exericise;public class exercise1 {public static void main(String[] args) {window t1 = new window();window t2 = new window();t1.setName("窗口1");t2.setName("窗口2");t1.start();t2.start();}
}package exericise;public class window extends Thread{static int ticket  =1000;@Overridepublic void run() {while (true) {synchronized (exercise1.class){if (ticket != 0){ticket--;try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(getName() + "还有"+ticket+"张票");}else {break;}}}}
}

package exericise;public class exercise2 {public static void main(String[] args) {Person t1 = new Person();Person t2 = new Person();t1.setName("Person1");t2.setName("Person2");t1.start();t2.start();}
}package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Person extends Thread {static int gift = 1000;static Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {lock.lock();try {if (!(gift < 10)) {System.out.println(getName() + "送出第" + gift + "个礼物");gift--;} else {break;}} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}}
}

package exericise;public class exercise3 {public static void main(String[] args) {Number t1 = new Number();Number t2 = new Number();t1.setName("线程1");t2.setName("线程2");t1.start();t2.start();}
}package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Number extends Thread{static int start = 1;static int end = 100;static Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {lock.lock();try {if (start <= end) {//判断是不是奇数if (start %2 == 1) {//是就打印System.out.println(getName() + ":" + start);}start++;}else {//超过范围break;}} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}}
}

package exericise;import java.util.Arrays;
import java.util.Random;public class exercise4 {public static void main(String[] args) {//随机分成3个红包Random r = new Random();for (int i = 0; i < redBao.arr.length; i++) {if (i == redBao.arr.length - 1) {redBao.arr[i] = redBao.redPocket;}else {redBao.arr[i] = r.nextDouble(0.01,redBao.redPocket);redBao.redPocket -= redBao.arr[i];}}System.out.println(Arrays.toString(redBao.arr));redBao rb1 = new redBao();redBao rb2 = new redBao();redBao rb3 = new redBao();redBao rb4 = new redBao();redBao rb5 = new redBao();rb1.setName("No.1");rb2.setName("No.2");rb3.setName("No.3");rb4.setName("No.4");rb5.setName("No.5");rb1.start();rb2.start();rb3.start();rb4.start();rb5.start();}
}
package exericise;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class redBao extends Thread{static double redPocket = 100;//标记是否已经抢到过boolean flag = false;static double[] arr = new double[3];static Lock lock = new ReentrantLock();static int index = 0;static int end = 1;@Overridepublic void run() {lock.lock();try {if (!flag && index <= 2){//还没抢到过红包System.out.println(getName() + "抢到了" + arr[index] + "块钱");index++;flag = true;}if (end >3) {System.out.println(getName() + "没抢到");}end++;} catch (Exception e) {throw new RuntimeException(e);} finally {lock.unlock();}}
}

在run方法中定义一个集合,则所有的进程都会在自己的栈中的run方法里创建出自己的集合,这个集合在不同的进程中独立,互不影响

注意:其实每一个线程都会有自己独立的栈,包括main,里面创建的元素互不影响(除非是static)

线程池

创建线程浪费时间

用完直接丢弃,浪费资源

原理

一般不会关闭线程池:因为服务器24小时都会运行,所以随时都会新任务进来,所以一般不会关闭线程池

Submit:提交任务

Shutdown:销毁线程池

0

自定义线程池

什么时候创建临时线程?

核心线程已被占用,而且排队队伍已满,这是才创建临时线程

先提交的任务,不一定先执行

如图,任务4 5 6在排队,临时线程处理任务7 8

当提交的任务数量大于核心线程数+临时线程数+队伍长度,剩下的任务10就会触发任务拒绝策略

自定义线程池,设置七个参数

ThreadPoolExecutor

到底怎么设置才合适?

最大并行数

系统处理器的线程数,4核8线程,8就是最大并行数

CPU密集型运算:读取文件较少,计算数据较多

为什么+1:如果前面的线程出问题,则多出来的线程就可以顶上,不浪费cpu的时钟周期不被浪费

IO密集性运算:现在的项目大多都是IO密集性的,读取服务器文件操作多

怎么得到计算时间?

通过thread dump的工具来测试计算时间

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win11 环境配置 之 Jmeter(JDK17版本)

一、安装 JDK 1. 安装 jdk 截至当前最新时间&#xff1a; 2024.3.27 jdk最新的版本 是 官网下载地址&#xff1a; https://www.oracle.com/java/technologies/downloads/ 建议下载 jdk17 另存为到该电脑的 D 盘下&#xff0c;新建jdk文件夹 开始安装到 jdk 文件夹下 2. 配…

C#基础知识总结

C语言、C和C#的区别 ✔ 面向对象编程&#xff08;OOP&#xff09;&#xff1a; C 是一种过程化的编程语言&#xff0c;它不直接支持面向对象编程。然而&#xff0c;C 是一种支持 OOP 的 C 的超集&#xff0c;它引入了类、对象、继承、多态等概念。C# 是完全面向对象的&#xff…

neo4j相同查询语句一次查询特慢再次查询比较快。

现象&#xff1a; neo4j相同查询语句一次查询特慢再次查询比较快。 分析&#xff1a; 查询语句 //查询同名方法match(path:Method) where id(path) in [244333030] and NOT path:Constructor//是rpc的方法match(rpc_method:Method)<-[:DECLARES]-(rpc_method_cls:Class) -…

实现ls -l 功能,index,rindex函数的使用

index(); rindex();----------------------------------------------------------------- index第一次遇到字符c&#xff0c;rindex最后一次遇到字符c&#xff0c;返回值都是从那个位置开始往后的字符串地址 #include <stdio.h> #include <sys/types.h> #include &…

【2023】kafka入门学习与使用(kafka-2)

目录&#x1f4bb; 一、基本介绍1、产生背景2、 消息队列介绍2.1、消息队列的本质作用2.2、消息队列的使用场景2.3、消息队列的两种模式2.4、消息队列选型&#xff1a; 二、kafka组件1、核心组件概念2、架构3、基本使用3.1、消费消息3.2、单播和多播消息的实现 4、主题和分区4.…

阿里云2核4G服务器租用价格_30元3个月_165元一年_199元

阿里云2核4G服务器租用优惠价格&#xff0c;轻量2核4G服务器165元一年、u1服务器2核4G5M带宽199元一年、云服务器e实例30元3个月&#xff0c;活动链接 aliyunfuwuqi.com/go/aliyun 活动链接如下图&#xff1a; 阿里云2核4G服务器优惠价格 轻量应用服务器2核2G4M带宽、60GB高效…

智慧城市数字孪生,综合治理一屏统览

现代城市作为一个复杂系统&#xff0c;牵一发而动全身&#xff0c;城市化进程中产生新的矛盾和社会问题都会影响整个城市系统的正常运转。智慧城市是应对这些问题的策略之一。城市工作要树立系统思维&#xff0c;从构成城市诸多要素、结构、功能等方面入手&#xff0c;系统推进…

Python面对对象 - 类的反射机制

Python面对对象类的反射机制是面向对象编程语言中比较重要的功能&#xff0c;可以动态获取对象信息以及动态调用对象。通过字符串形式的类名或属性来访问对应类或属性。 一、对象的反射 1. getattr 获取指定字符串名称的对象属性、方法&#xff1a; 当访问的属性不存在时&#…

微服务(基础篇-007-RabbitMQ)

目录 初识MQ(1) 同步通讯&#xff08;1.1&#xff09; 异步通讯&#xff08;1.2&#xff09; MQ常见框架&#xff08;1.3&#xff09; RabbitMQ快速入门(2) RabbitMQ概述和安装&#xff08;2.1&#xff09; 常见消息模型&#xff08;2.2&#xff09; 快速入门&#xff…

分布式理论:CAP理论 BASE理论

文章目录 1. CAP定理1.1 一致性1.3 分区容错1.4 矛盾 2. BASE理论3. 解决分布式事务的思路4. 扩展 解决分布式事务问题&#xff0c;需要一些分布式系统的基础知识作为理论指导。 1. CAP定理 Consistency(一致性): 用户访问分布式系统中的任意节点&#xff0c;得到的数据必须一…

【opencv】教程代码 —features2D(2)

使用SURF算法检测两幅图关键点后暴力匹配 SURF特征检测 使用SURF&#xff08;Speeded Up Robust Features&#xff09;算法来检测两张图像之间的关键点&#xff0c;并使用FLANN&#xff08;Fast Library for Approximate Nearest Neighbors&#xff09;基于特征描述符向量进行匹…

Windows中忘记MySQL ROOT密码的解决方法

在需要ROOT身份登录MySQL但又忘记密码时&#xff0c;可以先已管理员身份运行cmd命令窗口,输入以下命令停止MySQL服务 net stop mysql 随后cd到MySQL安装目录下的bin目录下 D: //我的安装在D盘 cd D:\MySQL\bin 使用跳过权限验证的方式起启动MySQL mysqld --console --skip-g…

跨境电商IP防关联是什么?有什么作用?

做跨境电商的朋友应该都知道IP防关联这个词,那么为何IP需要防关联呢&#xff1f;今天为大家来解答这个问题。 跨境电商IP防关联是指在跨境电商运营中&#xff0c;通过采取一系列技术手段&#xff0c;确保每个跨境电商账号使用独立的IP地址&#xff0c;以避免账号之间因为IP地址…

搜索与图论——Kruskal算法求最小生成树

kruskal算法相比prim算法思路简单&#xff0c;不用处理边界问题&#xff0c;不用堆优化&#xff0c;所以一般稀疏图都用Kruskal。 Kruskal算法时间复杂度O(mlogm) 每条边存结构体里&#xff0c;排序需要在结构体里重载小于号 判断a&#xff0c;b点是否连通以及将点假如集合中…

Linux重点思考(下)--shell脚本使用以及内核开发

Linux重点思考(下&#xff09;--shell脚本使用和组合拳 shell脚本的基础算法shell脚本写123...n的值&#xff0c;说思路Shell 脚本用于执行服务器性能测试的死循环Shell 脚本备份和定时清理垃圾文件 shell脚本的内核开发正向映射反向映射 shell脚本的基础算法 shell脚本写123……

link 样式表是否会阻塞页面内容的展示?取决于浏览器,edge 和 chrome 会,但 firefox 不会。

经过实测&#xff1a; 在 head 中 link 一个 1M 大小的样式表。设置网络下载时间大概为 10 秒。 edge 和 chrome 只有在下载完样式表后&#xff0c;页面上才会出现内容。而 firefox 可以直接先显示内容&#xff0c;然后等待样式表下载完成后再应用样式。 DOMContentLoaded 事…

vue系统——v-html

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>v-html指令</title> </head> <body&…

OSPF基本原理和概念

文章目录 背景知识OSPF协议概述&#xff1a;OSPF区域的表示OSPF 骨干区域 –区域0OSPF 非骨干区域 -非0区域OSPF的五种区域类型OSPF工作原理OSPF 的报文类型OSPF邻居表中的七个状态 总结 背景知识 一台路由设备如何获取其他网段的路由&#xff0c;并加入到路由表中 直连路由 …

虚拟机 centos 安装后与主机 ip保持一致

1、安装时 网络模式 悬着自动检测 &#xff08;桥接&#xff09; 2、打开网络 这里如果没有打开 就去 编辑 该文件。把ONBOOTno 改为yes 后 vim /etc/sysconfig/network-scripts/ifcfg-ens160 刷新配置 systemctl restart network 再查看addr 与本机 192.168.31.xx 在同…

Java23种常见设计模式汇总

七大原则网站地址&#xff1a;设计模式7大原则&#xff0b;类图关系-CSDN博客 创建型设计模式&#xff1a;创建型设计模式合集-CSDN博客 七大结构型设计模式&#xff1a;7大结构型设计模式-CSDN博客 11种行为型设计模式&#xff1a; 11种行为型模式&#xff08;上&#xff0…