Java两周半速成之路(第十五天)

一.多线程

1.线程的状态转换图

2. 线程组

2.1概述:

Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。

2.2构造方法

ThreadGroup(String name)           构造一个新的线程组

2.3成员方法:

public final String getName()                                      返回此线程组的名称

public final ThreadGroup getThreadGroup()              返回此线程所属的线程组

演示:

/*线程组:java可以将多个线程分装一个线程组中ThreadGroup*/class Demo extends Thread {private String name;private ThreadGroup threadGroup;public Demo() {super();}public Demo(ThreadGroup group, String name) {super(group, name);}@Overridepublic void run() {for (int i = 0; i <= 200; i++) {System.out.println(i);}}
}public class ThreadGroupDemo {public static void main(String[] args) {//构造方法//ThreadGroup(String name) 构造一个新的线程组。ThreadGroup threadGroup = new ThreadGroup("A线程组");//创建线程对象时候可以指定该线程是属于哪个线程组的Demo d1 = new Demo(threadGroup, "线程1");Demo d2 = new Demo(threadGroup, "线程2");//ThreadGroup类中有一个方法public final String getName()返回此线程组的名称。System.out.println(threadGroup.getName());//public final ThreadGroup getThreadGroup()返回此线程所属的线程组System.out.println(d1.getThreadGroup());ThreadGroup threadGroup1 = new ThreadGroup("守护线程组");Demo d3 = new Demo(threadGroup1, "线程3");Demo d4 = new Demo(threadGroup1, "线程4");//可以直接对线程组进行设置,线程组中的线程也一并进行设置threadGroup1.setDaemon(true);               //设置为守护线程组}
}

3.线程池

1.概述:

线程池:java提供了一个工具类Executors帮助我们创建不同种类的线程池

2.常用的线程池:

(1)FixedThreadPool(固定大小线程池)

  • 这个线程池创建固定数量的线程,一旦线程池创建完成,池中的线程数量将不再变化。
  • 适用于执行长期任务,例如网络爬虫。

(2)CachedThreadPool(缓存线程池)

  • 这个线程池的线程数量会根据需求动态变化,如果有可用的空闲线程,就会重用它们;如果没有可用的线程,则创建新的线程。
  • 适用于执行大量的短期异步任务,例如处理I/O操作。

(3)ScheduledThreadPool(定时线程池)

  • 这个线程池用于执行定时任务和周期性任务,例如执行定时的数据备份或者周期性的任务调度。
  • 可以根据需要指定线程数量。

(4)SingleThreadPool(单线程池)

  • 这个线程池只包含单个线程,所有任务按照顺序执行。
  • 适用于需要保证任务按照提交的顺序依次执行的情况。

(5)WorkStealingPool (任务窃取线程池)

  •  通常用于执行需要大量并行处理的任务
  • 在工作窃取算法中,每个线程都有自己的任务队列,但是当一个线程执行完自己队列中的任务后,它会去其他线程的队列中“窃取”任务来执行,可以提高效率。

下面我们主要说第一个线程池的应用:

/*线程池:java提供了一个工具类Executors帮助我们创建不同种类的线程池public static ExecutorService newFixedThreadPool(int nThreads)  固定大小的线程池线程的创建第三种方式:实现Callable接口,结合线程池创建。面试题:1、多线程的创建方式有几种,分别是哪几种?2、线程池有哪些?分别什么特点。*/import com.shujia.day13.Demo1;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;class Demo2 implements Callable {private String name;public Demo2(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic Object call() throws Exception {for (int i = 1; i <= 200; i++) {System.out.println(getName()+":"+i);}return null;}
}public class ThreadPoolDemo {public static void main(String[] args) {//创建一个线程池ExecutorService pool = Executors.newFixedThreadPool(2);//创建线程,使用创建线程的第三种方式CallableDemo2 demo2 = new Demo2("线程1");Demo2 demo3 = new Demo2("线程2");//将线程放入到线程组中运行//Future<?> submit(Runnable task);pool.submit(demo2);pool.submit(demo3);//关闭线程池pool.shutdown();}}

注意:

 submit()方法中的线程对象只能是实现Callable和Runable接口的,所以在此我们引出第三种创建线程的方式,那就是创建实现Callable接口的类并重写其中的call()方法。通常此方法创建的线程会结合线程池使用。

  使用匿名内部类改写:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolDemo {public static void main(String[] args) {//创建一个线程池ExecutorService pool = Executors.newFixedThreadPool(2);//因为是接口的实现,我们可以使用匿名内部类进行改写pool.submit(new Callable<Object>() {@Overridepublic Object call() throws Exception {for (int i = 1; i <= 200; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}return null;}});pool.submit(new Callable<Object>() {@Overridepublic Object call() throws Exception {for (int i = 1; i <= 200; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}return null;}});//关闭线程池pool.shutdown();}}

4.定时器

概述: 定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台线程的方式执行。在Java中,可以通过Timer和TimerTask类来实现定义调度的功能

Timer的构造方法以及成员方法:

Timer public Timer()                                                       构造方法,创建一个定时器对象

public void schedule(TimerTask task, long delay)          定时一个延时任务 只会执行一次

public void schedule(TimerTask task,long delay,long period)

延迟执行任务之后,以后的每间隔一段时间重复执行

TimerTask(抽象类):

TimerTask public abstract void run()            该定时器要做的操作

public boolean cancel()                                关闭定时器

定时任务演示:

import javafx.scene.input.DataFormat;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;/*在Java中,可以通过Timer和TimerTask类来实现定义调度的功能*/
public class TimerDemo {public static void main(String[] args) {//Timer() 创建一个新的计时器。Timer timer = new Timer();//设置定时任务//public void schedule(TimerTask task, long delay) 定时一个延时任务 只会执行一次timer.schedule(new Demo3(timer), 5000);       //毫秒级别//public void schedule(TimerTask task,long delay,long period) 延迟执行任务之后,以后的每间隔一段时间重复执行timer.schedule(new Demo3(timer), 5000, 3000);}
}class Demo3 extends TimerTask {private Timer timer;public Demo3(Timer timer) {this.timer = timer;}@Overridepublic void run() {Date date = new Date(System.currentTimeMillis());if(new SimpleDateFormat("yyyy年MM月dd日 HH:mm :ss").format(date).equals("2024年3月14日 21:15 :30")){timer.cancel();System.out.println("该定时器已经关闭");}else {System.out.println("叮当叮当,快点开始敲代码~");}}
}

5. 设计模式

1.概述:

 2.简单工厂模式:

概述:有一个类专门负责创建各种对象的,不需要在main方法中自己new

我们来举个列子来解释这个模式:

       假如有一个Animal类,还有Cat类和Dog类都继承子Animal类,我们可以另外写一AnimalFactory类来专门来创建Cat类和Dog类的对象,而不是在main方法中去new,可以将AnimalFactory类的构造方法私有化,成员方法静态,使它变成一个工具类,这样我们在测试类要用到Cat和Dog对象的时候可以直接调用类方法去获取对象。

3.工厂方法模式

还是以上个猫狗例子举例:

      我们也可以直接用CatFactory和DogFactory去创建各自的对象,而不是在AnimalFactory中去创建,在测试类中创建CatFactory和DogFactory对象对调用各自的创建方法去获取对象。

以上两种模式各自的优缺点:

如果创建动物的种类过多,简单工厂模式的AnimalFactory类就要去频繁的修改添加,工厂方法模式只需要新写一个该动物的工厂类就行,总的来说工厂方法模式脉络看起来更为清晰,但是代码量要比简单工厂模式稍多。

4.单例模式

(1)概述:

单(单一)例(实例)模式:整个java程序运行过程中,一个类的对象在内存中有且仅有一个

1. 构造方法私有化

2. 将自己类作为静态成员变量类型存在

3. 提供静态公共的成员方法获取这个对象

(2)分类:

                      a.懒汉式

                      b.饿汉式

(3)懒汉式:当调用获取对象的方法的时候,内存才会创建该类的对象

演示:

//懒汉式:class LazyDemo {private static LazyDemo lazydemo;private LazyDemo() {}public static LazyDemo getLazydemo() {if (lazydemo == null) {lazydemo = new LazyDemo();return lazydemo;} else {return lazydemo;}}
}public class Lazy {public static void main(String[] args) {LazyDemo lazydemo1 = LazyDemo.getLazydemo();LazyDemo lazydemo2 = LazyDemo.getLazydemo();System.out.println(lazydemo1 == lazydemo2);        // //true      说明对象在内存中有且仅有一个}
}

(4)饿汉式:无论是否调用获取对象的方法,内存中始终都会有且仅有一个该类对象

演示:

//懒汉式:
class HungruDemo {private static HungruDemo hungruDemo = new HungruDemo();private HungruDemo() {}public static HungruDemo getHungruDemo() {return hungruDemo;}
}public class Hungry {public static void main(String[] args) {HungruDemo hungruDemo1 = HungruDemo.getHungruDemo();HungruDemo hungruDemo2 = HungruDemo.getHungruDemo();System.out.println(hungruDemo1==hungruDemo2);   //true}
}

注意: 懒汉式涉及线程安全的问题,饿汉式不涉及。

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

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

相关文章

Day34:安全开发-JavaEE应用反射机制攻击链类对象成员变量方法构造方法

目录 Java-反射-Class对象类获取 Java-反射-Field成员变量类获取 Java-反射-Method成员方法类获取 Java-反射-Constructor构造方法类获取 Java-反射-不安全命令执行&反序列化链构造 思维导图 Java知识点 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;…

【Vue2】组件通信

父子通信 父 -> 子 子 -> 父 props 校验 props: {校验的属性名: {type: 类型, // Number String Boolean ...required: true, // 是否必填default: 默认值, // 默认值validator (value) {// 自定义校验逻辑return 是否通过校验}} },data 的数据是自己的 → 随便改pr…

数据和类型转换

文章目录 数据类型数字类型数字操作NaNJavaScript算术运算符的执行顺序 字符串类型&#xff08;string&#xff09;字符串拼接模板字符串 未定义类型&#xff08;undefined&#xff09;布尔类型&#xff08;boolean&#xff09;null&#xff08;空类型&#xff09; 类型转换显式…

Yolo系列算法-理论部分-YOLOv3

0. 写在前面 YOLO系列博客&#xff0c;紧接上一篇Yolo系列算法-理论部分-YOLOv2-CSDN博客 1. YOLOv3-定型之作 2018年&#xff0c;Redmon团队推出YOLOv3的网络模型&#xff0c;将骨干网络&#xff08;backbone&#xff09;由darknet-19替换成darknet-53网络&#xff0c;加入特…

精品基于Uniapp+ssm模拟考试系统小程序考试试题试卷

《[含文档PPT源码等]精品微信小程序基于Uniappssm模拟考试系统小程序》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 后台框架&#xff1a;ssm 安卓框架&a…

守护健康,从营养开始 —— 帕金森患者的饮食秘籍

亲爱的读者朋友们&#xff0c;您是否知道&#xff0c;在对抗帕金森病的道路上&#xff0c;正确的饮食和营养补充可以成为我们的有力盟友&#xff1f;今天&#xff0c;就让我们一起探索那些能够帮助帕金森患者改善症状、提高生活质量的营养素&#xff0c;开启健康生活的新篇章。…

《父母的觉醒》父母不是在培养一个“迷你版”的自己

简介 作者为美国哥伦比亚大学心理学博士沙法丽萨巴瑞。作者也写了《家庭的觉醒》。 作者的核心观点&#xff1a; 我们必须认识到&#xff0c;我们不是在培养一个“迷你版”的自己&#xff0c;而是在塑造一个具有独立特征的灵魂。正因为如此&#xff0c;我们必须铆足精神&#…

ETH共识升级之路

简介 根据我们之前的介绍&#xff0c;了解到ETH网络的共识方式&#xff0c;已经从 PoW 切换到了 PoS&#xff0c;今天我们就回顾下升级之路&#xff0c;以及升级带来的影响 最早的共识机制 PoW 以太坊创建之初采用了类似比特币的工作量证明机制&#xff0c;即矿工通过计算哈希函…

JAVA实战开源项目:计算机机房作业管理系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 课程管理模块2.3 课时管理模块2.4 学生作业模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程表3.2.2 课时表3.2.3 学生作业表 四、系统展示五、核心代码5.1 查询课程数据5.2 新增课时5.3 提交作…

【消息队列开发】 实现消息删除逻辑

文章目录 &#x1f343;前言&#x1f332;实现步骤&#x1f6a9;检验参数的合法性&#x1f6a9;读取Message数据&#x1f6a9;二进制转为message&#x1f6a9;isValid 设置为无效&#x1f6a9;写入文件&#x1f6a9;更新统计文件&#x1f6a9;特别注意&#x1f6a9;完整代码 ⭕…

运动想象 (MI) 迁移学习系列 (9) : 数据对齐(EA)

运动想象迁移学习系列:数据对齐&#xff08;EA&#xff09; 0. 引言1. 迁移学习算法流程2. 欧式对齐算法流程3. 与RA算法进行对比4. 实验结果对比5. 总结欢迎来稿 论文地址&#xff1a;https://ieeexplore.ieee.org/abstract/document/8701679 论文题目&#xff1a;Transfer Le…

【论文阅读】MoCoGAN: Decomposing Motion and Content for Video Generation

MoCoGAN: Decomposing Motion and Content for Video Generation 引用&#xff1a; Tulyakov S, Liu M Y, Yang X, et al. Mocogan: Decomposing motion and content for video generation[C]//Proceedings of the IEEE conference on computer vision and pattern recognitio…