多线程入门

文章目录

  • 多线程相关的概念
  • 什么是多线程
  • 多线程的创建方式
    • 继承Thread方式
    • 实现Runable方式
    • 两种方式比较
    • Thread类中常用方法


在这里插入图片描述

多线程相关的概念

  • 并发与并行
    • 并行:在同一时刻,有多个任务在多个CPU上同时执行。
    • 并发:在同一时刻,有多个任务在单个CPU上交替执行。
  • 进程与线程
    • 进程:就是操作系统中正在运行的一个应用程序。
    • 线程:就是应用程序中做的事情。比如:360软件中的杀毒,扫描木马,清理垃圾。

什么是多线程

  • 是指从软件或者硬件上实现多个线程并发执行的技术。
    具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。
  • 好处 : 提高任务的执行性能

多线程的创建方式

继承Thread方式

基本步骤:

  • 创建一个类继承 Thread 类。
  • 在类中重写run方法(线程执行的任务放在这里)
  • 创建线程对象,调用线程的start方法开启线程。
  • 执行程序,观察控制台的打印数据的现象
/*线程的创建方式1:继承Thread方式基本步骤 :1 创建一个类继承Thread类。2 在类中重写run方法(线程执行的任务放在这里)3 创建线程对象,调用线程的start方法开启线程。需求 :我们启动一个Java程序,其实默认就存在一个主线程(main方法所在线程)接下来,我们在主线程启动一个线程,打印1到100的数字,主线程启动完线程后又打印1到100的数字。此时主线程和启动的线程在并发执行,观察控制台打印的结果。*/
public class MyThread01 {public static void main(String[] args) {// 创建线程对象,调用线程的start方法开启线程。MyThread mt = new MyThread();mt.start();// main方法中的任务for (int i = 1; i <= 100; i++) {System.out.println("i:" + i);}}
}
// 创建一个类继承Thread类。
class MyThread extends Thread {// 在类中重写run方法(线程执行的任务放在这里)@Overridepublic void run() {for (int i = 1; i <= 100; i++) {System.out.println("i:" + i);}}
}

实现Runable方式

  • 构造方法

    • public Thread(Runnable target)
    • public Thread(Runnalbe target , String name)
  • 实现步骤

    • 定义任务类实现Runnable,并重写run方法
    • 创建任务对象
    • 使用含有Runnable参数的构造方法,创建线程对象并指定任务。
    • 调用线程的start方法,开启线程
/*线程的创建方式2:实现Runnable方式基本步骤 :1 定义任务类实现Runnable,并重写run方法2 创建任务对象3 使用含有Runnable参数的构造方法,创建线程对象并指定任务。4 调用线程的start方法,开启线程需求 :我们启动一个Java程序,其实默认就存在一个主线程(main方法所在线程)接下来,我们在主线程启动一个线程,打印1到100的数字,主线程启动完线程后又打印1到100的数字。此时主线程和启动的线程在并发执行,观察控制台打印的结果。*/
public class MyThread02 {public static void main(String[] args) {// 创建线程对象,调用线程的start方法开启线程。MyRunnable mr = new MyRunnable();Thread thread= new Thread(mr);thread.start();// main方法中的任务for (int i = 1; i <= 100; i++) {System.out.println("i:" + i);}}}// 1 定义任务类实现Runnable,并重写run方法
class MyRunnable implements Runnable {// 在类中重写run方法(线程执行的任务放在这里)@Overridepublic void run() {for (int i = 1; i <= 100; i++) {System.out.println("i:" + i);}}
}

两种方式比较

实现方式优点缺点
实现 Runnable扩展性强
实现接口的同时还可以继承其他的类
编程相对复杂
不能直接使用Thread中的方法
继承 Thread编程比较简单
可以直接使用Thread中的方法
可扩展性差
不能再继承其他的类

Thread类中常用方法

  • String getName():返回此线程的名称

  • Thread类中设置线程的名字

    • void setName(String name):将此线程的名称更改为等于参数 name
    • 通过构造方法也可以设置线程名称
  • public static Thread currentThread():返回对当前正在执行的线程对象的引用

  • public static void sleep(long time):让线程休眠指定的时间,单位为毫秒

  • public final synchronized void join(long millis):

当在使用多线程编程时,可能会创建多个线程来同时执行不同的任务。join 方法是一个用来管理线程执行顺序的重要工具。

当一个线程调用另一个线程的 join 方法时,它会等待被调用线程执行完成,然后再继续执行。换句话说,调用了 join
方法的线程会在被调用线程完成后才会结束。

这对于需要确保某些线程在其他线程执行完毕后再执行的情况非常有用。例如,如果你有一个主线程和两个子线程,主线程需要等待两个子线程都完成后再做某些处理,你就可以在主线程中调用两个子线程的
join 方法,这样主线程就会等待两个子线程都执行完毕后再继续执行。
需要注意的是,如果你不使用 join 方法,主线程和子线程可能会同时执行,这可能会导致竞争条件或其他问题。所以,在多线程编程中,合理地使用 join
方法可以确保线程的执行顺序和逻辑正确性。

  • 线程有两种调度模型

    • 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
    • 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些
    /*线程有两种调度模型1 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片2 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些注意 : Java使用的是抢占式调度模型优先级高 , 只是抢夺到cpu执行的概率高而已 , 只是一种概率问题*/
    public class PriorityDemo {public static void main(String[] args) {Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println(Thread.currentThread().getName() + ":" + i);}}});// 优先级最低thread1.setPriority(1);thread1.start();Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println(Thread.currentThread().getName() + ":" + i);}}});// 优先级最高thread2.setPriority(10);thread2.start();}
    }
    




在这里插入图片描述



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

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

相关文章

我与C++的爱恋:类与对象(二)

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 ​ 本篇着重介绍构造函数和析构函数&#xff0c;剩余内容在下篇解答。 一、类的默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 任何类在什么都不写时…

Vue - 5( 16000 字 Vue2 入门级教程)

一&#xff1a;Vue 初阶 1.1 组件自定义事件 在 Vue 中&#xff0c;组件间通过自定义事件进行通信是一种常见的模式。自定义事件允许子组件向父组件发送消息&#xff0c;也可以在组件内部进行事件的绑定、触发和解绑。让我们详细讲解这些知识点。 1.1.1 组件自定义事件 在 …

Python | Leetcode Python题解之第27题移除元素

题目&#xff1a; 题解&#xff1a; class Solution:def removeElement(self, nums: List[int], val: int) -> int:a 0b 0while a < len(nums):if nums[a] ! val:nums[b] nums[a]b 1a 1return b

Springboot+Vue项目-基于Java+MySQL的社区团购系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

社交媒体数据恢复:推特、Twitter

推特&#xff08;Twitter&#xff09;数据恢复&#xff1a;如何找回丢失的内容 随着社交媒体的普及&#xff0c;越来越多的人开始使用推特&#xff08;Twitter&#xff09;来分享生活点滴、发表观点和获取信息。然而&#xff0c;有时候我们会不小心删除了重要的推文&#xff0…

K8s下部署grafana

1. 系统要求 最小化的软硬件要求 最小化硬件要求 磁盘空间: 1 GB内存: 750 MiB (approx 750 MB)CPU: 250m (approx 2.5 cores) 2. k8s部署grafana步骤 1) 创建名字空间 kubectl create namespace my-grafana 2) 创建yaml vim grafana.yaml yaml包含如下三个资源对象 Ob…

Springboot+Vue项目-基于Java+MySQL的母婴商城系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

通过一篇文章让你了解Linux的重要性

Linux 前言一、什么是Linux后台vs前台为何大多数公司选择使用Linux作为后台服务器 二、国内企业后台和用户使用Linux现状IT服务器Linux系统应用领域嵌入式Linux系统应用领域个人桌面应用领域 三、就个人能力提升来说&#xff0c;该如何看待Linux网络上的人都怎么说知乎 腾讯面经…

006Node.js cnpm的安装

百度搜索 cnpm,进入npmmirror 镜像站https://npmmirror.com/ cmd窗口输入 npm install -g cnpm --registryhttps://registry.npmmirror.com

年龄与疾病c++

题目描述 某医院想统计一下某项疾病的获得与否与年龄是否有关&#xff0c;需要对以前的诊断记录进行整理&#xff0c;按照0-18岁、19-35岁、36-60岁、61以上&#xff08;含61&#xff09;四个年龄段统计的患病人数以及占总患病人数的比例。 输入 共2行&#xff0c;第一行为过…

【C++第三阶段】vector容器

以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 构造函数赋值操作容量和大小插入和删除数据存取互换容器预留空间 构造函数 vector函数是常用数据结构&#xff0c;见于刷题网站。 它是单端数组&#xff0c;与普通数组区别在于可以…

【数据结构与算法篇】单链表实现通讯录

【数据结构与算法篇】单链表实现通讯录(近350行实现代码) &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;数据结构与算法&#x1f345; 目录 1. SListContact.h 头文件的声明 2. SListContact.c 源文件的定义 3. Test.c 源文件的测…