day17_多线程基础

今日内容

零、 复习昨日
一、作业
二、进程与线程
三、创建线程
四、线程的API

一、复习

IO流的分类

  • 方向: 输入,输出
  • 类型: 字节(XxxStream),字符(XxxReader,XxxWriter)
  • 字节输入流类名: FileInputStream
  • 字节输出流类名: FileOutputStream
  • 字符输入流类名: FileReader
  • 字符输出流类名: FileWriter

利用try-catch-finally代码写法是重点

ArrayList和LinkedList的异同点

  • ArrayList 底层是数组,容量10,装满扩容1.5倍
  • LinkedList 底层是链表
  • 相同点: 都是存储多个元素,有序,且允许重复元素
  • 不同点: 底层实现原理不一样,AL查询更新快 LL插入删除较快

解析字符串日期为日期对象的方法签名
Date date = sdf.parse(“2020-01-01”);
Date parse(String s)

解析字符串数字为int数字的方法签名
static int parseInt(String s)

int n = Integer.parseInt(“1”);


String,Date,try-catch-finally
ArrayList,HashMap
认真,慢一点,写一遍(用法,解释,代码)到本上

二、进程与线程[了解]

进程:

一个进程就是一个应用程序,进程包含线程
一个进程至少包含一个线程,大部分都是有多条线程在执行任务(多线程),每个独立运行的程序都对应一个进程。进程是资源分配的最小单位,占用独立的内存空间和系统资源

  • qq,微信,迅雷

线程:

线程是进程内部的一个执行任务

进程内多个线程是共享进程资源,线程是资源调度的最小单位(CPU调度和分派的基本单位)

  • qq在聊天,视频,传输文件
  • 迅雷同时下载多个资源

Java程序是否是多线程的吗?
答: 是! main线程,gc垃圾回收线程

为什么需要多线程?

  • 并行处理任务,提高效率

Java程序本身,是否多线程?

  • 是,至少有一个线程是"main"线程
  • 还有一个线程是没有直接看到,但是一直在"背后"运行,垃圾回收线程(GC)

三、创建线程[重点]

Thread

创建线程的方式有很多

  • 继承Thread
  • 实现Runnable接口
  • 使用Callable 和FutureTask来完成
  • 使用线程池获得线程

3.1 继承Thread

步骤

  1. 自定义类
  2. 继承Thread
  3. 重写run方法
  4. 创建子类对象
  5. 调用start方法启动线程 [特别强调,开启新线程的方法是start]
    start方法内部执行时会调用run方法执行
public class MyThread extends Thread{// 重写方法,方法内部,就是该线程执行的任务@Overridepublic void run() {for (int i = 1; i < 101; i++) {System.out.println("MyThread --> "+i );}}
}
public class TestThread{public static void main(String[] args) {// 创建一个线程MyThread myThread = new MyThread( );// 启动线程,不是调用run()方法!!!!// 调用start方法开启新线程myThread.start();// ==============main线程执行====================for (int i = 1; i < 101; i++) {System.out.println("main     --> " + i );}// 自定义线程和主线程同时执行,并且出现资源争抢情况}
}

3.2 实现Runnable接口

步骤

  1. 自定义类
  2. 实现Runnable接口
  3. 重写run方法
  4. 创建子实现类对象
  5. 把子实现类对象当构造方法的方法参数来创建Thread对象
  6. 由thread调用start方法开启线程
public class MyRunnable implements Runnable{@Overridepublic void run() {for (int i = 1; i < 101; i++) {System.out.println("MyRunnable --> " + i);}}
}
    public static void main(String[] args) {// 4 创建实现类对象MyRunnable myRunnable = new MyRunnable( );// 5 把对象当构造方法参数,创建Thread对象Thread thread = new Thread(myRunnable);// 6 开启线程thread.start();}

匿名内部类的形式创建线程

// ============= 匿名内部类完成实现Runnable接口 ============
public class Demo4Annoy {public static void main(String[] args) {Runnable runnable = new Runnable( ) {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("匿名内部类 --> " + i);}}};Thread thread = new Thread(runnable);thread.start();// new Thread( new Runnable() {//     @Override//     public void run() {//         for (int i = 0; i < 100; i++) {//             System.out.println("匿名内部类 --> " + i );//         }//     }// }).start();for (int i = 0; i < 100; i++) {System.out.println("main --> " + i);}}
}

3.3 区别

继承Thread开启线程和实现Runnable接口开启线程有什么区别?


  • 一个继承,一个实现
  • 继承Thread后,直接创建对象即可调用start开启线程
  • 实现Runnable接口的子类,还需要再创建Thread类对象才可以调用strat开启线程

从使用便捷度来说,继承Thread开启线程会方便一点…因为创建完线程对象可以直接调用start开启线程

继承Thread类就限制了该类不能再继承别的类,因为类只能单继承,而实现接口的同时可以继承别的类,并且还允许多继承,所以推荐使用接口来实现多线程.

3.4 其他创建线程方式

package com.qf.thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;public class Callable01 {public static void main(String[] args) throws InterruptedException, ExecutionException {// FutureTask对象用于接收线程返回值, FutureTask 实现了RunnableFuture接口// public class FutureTask<V> implements RunnableFuture<V> {}// RunnableFuture接口继承了Runnable和Future接口,后面用到的get方法来自Future接口// public interface RunnableFuture<V> extends Runnable, Future<V>{}FutureTask<String> futureTask = new FutureTask<String>(new MyCallable());Thread thread = new Thread(futureTask);thread.start();System.out.println("-----------------");// 该语句阻塞程序的执行,等待线程执行完毕,获取线程返回的数据String result = futureTask.get();System.out.println(result);}
}// 实现Callable接口的类
class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {System.out.println(Thread.currentThread().getName());Thread.sleep(5000);return "haha";}
}

四、Thread的API[熟悉]

  • void start() 开启线程,会自动run方法执行线程任务
  • void run() 执行线程的方法
    • run() 方法是start开启线程后,JVM自动调用
  • void setName(String name) 给线程设置名字
    • 也可以通过构造方法,在创建线程时指定线程名
  • String getName() 获得线程的名字
  • static Thread currentThread() 返回当前正在执行的线程对象
  • join() 加入线程,等待该线程终止
  • join(int milles) 加入线程,最大等待直到毫秒数
  • void setDaemon(boolean on) 设置守护线程
  • static void sleep(long milles) 线程休眠
    • 会让当前线程暂停执行,让出系统资源,让其他线程执行
    • 时间到,当前会继续和其他争抢资源执行
  • void stop() 结束当前线程,线程死亡(已过式)
    • 被废弃的原因是因为这个中断线程太直接太暴力…

线程名字

  • String getName()
  • void setName()
  • Thread(String name)
package com.qf.thread_api;/*** --- 天道酬勤 ---** @author QiuShiju* @desc 关于线程名字操作*/
public class Demo1 {public static void main(String[] args) {new Thread(){@Overridepublic void run() {// 给线程设置名字this.setName("驴车");// 创建线程,默认会分配名字,安装thread-x来命名System.out.println("开启新线程,线程名: " + getName());}}.start();new Thread(){@Overridepublic void run() {this.setName("火车");// 创建线程,默认会分配名字,安装thread-x来命名System.out.println("开启新线程,线程名: " + getName());}}.start();new Thread(){@Overridepublic void run() {this.setName("飞机");// 创建线程,默认会分配名字,安装thread-x来命名System.out.println("开启新线程,线程名: " + getName());}}.start();Thread thread = new Thread(){@Overridepublic void run() {}};System.out.println(thread.getName( ));thread.setName("火箭");System.out.println(thread.getName( ));/*** 还可以通过构造方法,在创建线程时指定线程名*/Thread thread5 = new Thread("子弹头"){@Overridepublic void run() {}};System.out.println("线程5-->" + thread5.getName( ));}
}

获得当前线程对象

  • static Thread currentThread()
public static void main(String[] args) {new Thread("火车"){@Overridepublic void run() {Thread t = Thread.currentThread( );System.out.println(t.getName()+",在执行..." );}}.start();/*** 获得当前正在执行的线程对象*/Thread thread = Thread.currentThread( );System.out.println("当前正在执行的线程名字是: "+thread.getName( ));
}

线程加入

  • join()
  • join(long mill)
public static void main(String[] args) {Thread t1 = new Thread("线程1"){@Overridepublic void run() {for (int i = 1; i < 1001; i++) {System.out.println(getName()+"-->"+i );}}};Thread t2 = new Thread("线程2"){@Overridepublic void run() {for (int i = 1; i < 1001; i++) {System.out.println(getName()+"-->"+i );if (i == 100) {try {// 在当前线程下加入另一个线程// 相当于"插队",直到插入的线程执行完//t1.join();// 让另外一个线程加入指定时间,到时后继续争抢t1.join(10);} catch (InterruptedException e) {e.printStackTrace( );}}}}};t1.start();t2.start();
}

守护线程

  • void setDaemon(boolean x)

  • 守护线程是指,A线程守护B线程,即B是被保护,B是重要的,当B线程结束时A线程(守护线程)会立即结束

public static void main(String[] args) {Thread hs = new Thread("皇上"){@Overridepublic void run() {for (int i = 1; i < 11; i++) {System.out.println(getName()+"工作"+i+"天" );}}};Thread fz = new Thread("妃子"){@Overridepublic void run() {for (int i = 1; i < 101; i++) {System.out.println(getName()+"工作"+i+"天" );}}};/*** 不需要设置被守护,只需要设置守护线程,其他默认就是被守护线程* 开启线程前设置*/fz.setDaemon(true);hs.start();fz.start();
}

线程休眠

  • sleep(long millis)
  • 会让当前线程陷入等待状态(阻塞)状态,让其资源让其他线程执行
public static void main(String[] args) throws InterruptedException {for (int i = 10; i > 0; i--) {System.out.println("倒计时 --> " + i );Thread.sleep(1000);}System.out.println("发射!" );
}private static void show() {Thread t1 = new Thread("线程1"){@Overridepublic void run() {for (int i = 1; i < 101; i++) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace( );}System.out.println(getName()+"-->"+i );}}};Thread t2 = new Thread("线程2"){@Overridepublic void run() {for (int i = 1; i < 101; i++) {System.out.println(getName()+"-->"+i );}}};t1.start();t2.start();
}

结束线程

  • void stop() 结束当前线程
  • void interrupt() 设置线程中断状态为以中断
  • boolean isInterrupt() 测试返回线程是否中断
public static void main(String[] args) {new Thread("线程2"){@Overridepublic void run() {for (int i = 1; i < 101; i++) {if (i == 15){//this.stop(); // 直接结束线程this.interrupt();// 给线程设置一个中断状态,不会真的中断线程// 结束不结束取决于线程本身执行情况}System.out.println("是否中断? "+this.isInterrupted() );System.out.println(getName()+"-->"+i );}}}.start();
}

五、线程状态[面试]

线程的几种状态:

  • 创建/新建/初始
    • new 完线程对象
  • 就绪
    • 调用start
  • 等待/阻塞
    • join()或者sleep()
  • 运行
    • 执行run()方法
  • 死亡/销毁/终止
    • run方法执行完,或者调用stop()或者interrupt()中断等

清楚状态之间的转换

image-20230802165354147

image-20230302170320045

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

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

相关文章

bclinux aarch64 ceph 14.2.10 对象存储 http网关 CEPH OBJECT GATEWAY Civetweb

相关内容 bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds&#xff1a; ceph-deploy mds-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【3】vdbench fsd 文件系统测试-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【2】vdbench rbd 块设…

RabbitMQ之消息应答和持久化

文章目录 前言一、消息应答1.概念2.自动应答3.消息应答方法4.Multiple 的解释5.消息自动重新入队6.消息手动应答代码7.手动应答效果演示 二、RabbitMQ持久化1.概念2.队列如何实现持久化3.消息实现持久化4.不公平分发5.预取值 总结 前言 在RabbitMQ中&#xff0c;我们的消费者在…

Django之模版层

文章目录 模版语法传值模版语法传值特性模版语法标签语法格式if模板标签for模板标签with起别名 模版语法过滤器常用过滤器 自定义过滤器、标签、inclusion_tag自定义过滤器自定义标签自定义inclusion_tag 模版导入模版继承 模版语法传值 模板层三种语法{{}}:主要与数据值相关{%…

【LLM】0x00 大模型简介

0x00 大模型简介 个人问题学习笔记大模型简介LLM 的能力&#xff1a;LLM 的特点&#xff1a; LangChain 简介LangChain 核心组件 小结参考资料 个人问题 1、大模型是什么&#xff1f; 2、ChatGPT 在大模型里是什么&#xff1f; 3、大模型怎么用&#xff1f; 带着问题去学习&a…

Linux Centos 根目录扩展分区(保级教程)

Centos 根目录扩展分区 1. 扩展背景2.列出磁盘信息3. 对磁盘进行分区4. 重启Linux5. 将PV加入卷组centos并分区6.查看分区结果 1. 扩展背景 虚拟机初始分配20G内存&#xff0c;扩容到80G。 2.列出磁盘信息 可以得知容量信息以及即将创建的PV路径&#xff08;通常为“/dev/s…

2024上海国际智能驾驶技术展览会(自动驾驶展)

2024上海国际智能驾驶技术展览会 2024 Shanghai International Autonomous driving Expo 时间&#xff1a;2024年3月26-28日 地点&#xff1a;上海跨国采购会展中心 随着科技的飞速发展&#xff0c;智能驾驶已经成为了汽车行业的重要趋势。在这个时代背景下&#xff0c;汽车不…

Qt 线程串口

文章目录 ui设置创建线程函数初始串口run函数接收发送数据读取数据处理读取的数据写入数据写入启动的命令 主线程 ui设置 创建线程函数 #include <QObject> #include <QThread> #include <QSerialPort> #include <QSerialPortInfo>class SerialPort :…

微信小程序广告banner、滚动屏怎么做?

使用滑块视图容器swiper和swiper-item可以制作滚动屏&#xff0c;代码如下&#xff1a; wxml: <swiper indicator-dots indicator-color"rgba(255,255,255,0.5)" indicator-active-color"white" autoplay interval"3000"><swiper-ite…

Unity Meta Quest 一体机开发(六):HandGrabInteractor 和 HandGrabInteractable 知识点

文章目录 &#x1f4d5;教程说明&#x1f4d5;HandGrabInteractor⭐HandGrabAPI⭐HandWristPoint⭐GripPoint⭐PinchPoint⭐PinchArea⭐HandGrabVisual⭐HandGrabGlow &#x1f4d5;HandGrabInteractable⭐Support Grab Type⭐Pinch Grab Rules 和 Palm Grab Rules⭐Unselect M…

【Java 进阶篇】JQuery 案例:全选全不选,为选择添彩

在前端的舞台上&#xff0c;用户交互是一场精彩的表演&#xff0c;而全选全不选的功能则是其中一段引人入胜的剧情。通过巧妙运用 JQuery&#xff0c;我们可以为用户提供便捷的全选和全不选操作&#xff0c;让页面更富交互性。本篇博客将深入探讨 JQuery 中全选全不选的实现原理…

pytorch tensor数据类型转换为python数据

一、item() input: x torch.tensor([1.0]) x.item()output: 1.0二、tolist() input: a torch.randn(2, 2) a.tolist() a[0,0].tolist()output: [[0.012766935862600803, 0.5415473580360413],[-0.08909505605697632, 0.7729271650314331]]0.012766935862600803

【论文阅读】(CTGAN)Modeling Tabular data using Conditional GAN

论文地址&#xff1a;[1907.00503] Modeling Tabular data using Conditional GAN (arxiv.org) 摘要 对表格数据中行的概率分布进行建模并生成真实的合成数据是一项非常重要的任务&#xff0c;有着许多挑战。本文设计了CTGAN&#xff0c;使用条件生成器解决挑战。为了帮助进行公…

IDEA如何打断点调试

目录 1. 设置断点2. 调试3. 调试的基本操作3.1 step over3.2 step into 跟 Force step into3.3 step out3.4 resume program3.5 mute breakpoints3.6 view breakpoints3.6 条件断点 编写代码的时候&#xff0c;有时候我们需要跟踪代码的运行情况&#xff0c;使用断点调试就是一…

Eclipse打包Springboot项目

首先&#xff0c;在pom.xml文件中添加配置&#xff0c;修改mainClass主函数&#xff1a; <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configurat…

蓝桥杯每日一题2023.11.14

题目描述 题目分析 此题目的最终目标是将字母都填上数使等式符合条件&#xff0c;实际我们发现可以使用搜索将所有符合条件的进行判断&#xff08;答案&#xff1a;29&#xff09; 由于小数可能会出现错误故我们将其进行简单变化进行搜索 #include<bits/stdc.h> using…

Git常用指令以及常见问题解决

摘要&#xff1a;记录本人Git常用指令以及常见问题解决 1.Git流程 2.具体操作 git init&#xff1a;初始化目录&#xff08;一般直接git clone远端的工程&#xff0c;这一步都可以省略掉&#xff09;&#xff1b; 输入命令“git config --global user.name xxx”来配置你的用…

wpf devexpress设置行和编辑器

如下教程示范如何计算行布局&#xff0c;特定的表格单元编辑器&#xff0c;和格式化显示值。这个教程基于前一个文章 选择行显示 GridControl为所有字段生成行和绑定数据源&#xff0c;如果AutoGenerateColumns 属性选择AddNew。添加行到GridControl精确显示为特别的几行设置。…

【力扣题:循环队列】

文章目录 一.题目描述二. 思路解析三. 代码实现 一.题目描述 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好…

贪吃蛇小游戏代码

框架区 package 结果;import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.util.ArrayList; import java.util.List; import java.util.Random;import javax.s…

k8s之Helm

理论&#xff1a; 什么是 He lm 在没使用 helm 之前&#xff0c;向 kubernetes 部署应用&#xff0c;我们要依次部署 deployment、svc 等&#xff0c;步骤较繁琐。 况且随着很多项目微服务化&#xff0c;复杂的应用在容器中部署以及管理显得较为复杂&#xff0c;helm 通过打包…