Java,多线程,线程的两种创建方式

首先是多线程的一些相关概念:

相关概念:

程序(program):为完成特定任务,用某种语言编写的一组指令的集合。即指一段静态(指不在执行中)的代码。

进程(process):程序的一次执行过程,或是正在内存中运行的应用程序。

        ·每个进程都有一个独立的内存空间,系统运行一个程序即是一个进程从创建、运行到消亡的过程。(声明周期)

        ·程序是静态的,进程是动态的。

        ·进程作为操作系统调度和分配资源的最小单位(亦是系统运行程序的基本单位),系统在运行时会为每个进程分配不同的内存区域。

线程(thread):进程可以进一步细化为线程,时程序内部的一条执行路径。一个进程中至少有一个线程。

        ·一个进程同一时间若并行执行多个线程,就是多线程的。

        ·线程是作为CPU调度和执行的最小单位。

        ·一个进程中的多个线程共享相同的内存单元,它们从一个堆中分配对象,可以访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资源就可能会带来安全的隐患。

        注:不同的进程之间是不共享内存的。进程之间的数据交换和通信的成本很高。

线程调度:

        ·分时调度:所有线程轮流使用CPU的使用权,并且平均分配每个线程占用CPU的时间。

        ·抢占式调度:让优先级高的线程以较大的概率优先使用CPU。如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

多线程程序的优点:

        提高应用程序的响应。对图形化界面更有意义,可增强用户体验。

        提高计算机系统CPU的利用率。

        改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改。

并行与并发:

并行(parallel):指两个或多个事件在同一时刻发生。指在同一时刻,有多条指令在多个CPU上同时执行。

并发(concurrency):指两个或多个事件在同一个时间段内发生。即在同一段时间内,有多条指令在单个CPU上快速轮换、交替执行,使得在宏观上具有多个进程同时执行的效果。

Java,多线程,线程创建方式一:继承Thread类

 Java语言的JVM允许程序运行多个线程,使用java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。

Thread类的特性:

    ①每个线程都是通过某个特定的Thread对象的run( )方法来完成操作的,因此把run( )方法称为线程执行体。

    ②通过该Thread对象的start( )方法来启动这个线程,而非直接调用run( )方法。

    ③想要实现多线程,必须在主线程中创建新的线程对象。

通过继承Thread类来创建并启动多线程的步骤如下:

①定义Thread的子类,并重写该类的run( )方法,该run( )方法的方法体就代表了线程需要完成的任务。

②创建Thread类的子类的实例,即创建了线程对象。

③调用线程对象的start( )方法来启动该线程。

start( )的作用:①启动线程②调用当前线程的run( )方法。

以下代码的实现为例:

两个线程分别遍历10000以内的偶数:

public class EvenNumberTest{public static void main(String[] args){//③创建当前Thread类的子类的对象PrintNumber t1 = new PrintNumber();//通过对象调用start()方法t1.start();//main方法所在的线程的执行的操作for (int i = 1; i <= 10000; i++){if(i % 2 == 0){System.out.println(i + "及你太美");}}}
}//①创建一个继承于Thread的子类
class PrintNumber extends Thread
{//②重写Thread类的run方法,并将此线程的要执行的操作,声明在此方法体中@Overridepublic void run(){for (int i = 1; i <= 10000; i++){if(i % 2 == 0){System.out.println(i);}}}
}

可以发现到两个进程的交替的运行的状况:

注意点一:

如果不调用start( )方法,直接调用run( )方法,便不会开启新的线程。

注意点二:

不能让已经start的线程,再次执行start( ),否则会报异常。正确做法应该是再创建一个新的对象,用新的对象调用start( )方法。

可以利用匿名内部类的方法写出   遍历100以内的奇数和偶数的俩个线程(创建两个匿名内部类(Thread类的子类的匿名)):

class EvenNumber extends Thread
{@Overridepublic void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
}class OddNumber extends Thread
{@Overridepublic void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 1){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
}public class PrintNumberTest{public static void main(String[] args{
//        EvenNumber e = new EvenNumber();
//        OddNumber o = new OddNumber();
//        e.start();
//        o.start();//方式二new Thread(){public void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}}.start();new Thread(){public void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 1){System.out.println(Thread.currentThread().getName() + ": " + i);}}}}.start();}
}

Java,多线程,线程创建方式二:实现Runnable接口

步骤:

①创建一个实现Runnable接口的类

②实现接口中的run( )方法,将此线程要执行的操作,声明在此方法体中。

③创建当前实现类的对象

④将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例。

⑤Thread类的实例调用start( )方法。

基本步骤的样例如下:

//①创建一个实现Runnable接口的类
class EvenNumberPrint implements Runnable
{
//②创建接口中的run()方法,将此线程要执行的操作,声明在此方法体中@Overridepublic void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
}
public class EvenNumberTest
{public static void main(String[] args){EvenNumberPrint e = new EvenNumberPrint();//创建Runnable类的实现类的对象。Thread thread = new Thread(e);//创建thread类的对象,调用参数为Runnable的实现类的构造器,将实现类的对象代入构造器中去。thread.start();//直接调用Thread的对象的start方法。for (int i = 1; i <= 100; i++){if(i % 2 == 1){System.out.println(Thread.currentThread().getName() + ": " + i);}}Thread tt = new Thread(e);//要再创建一条新的线程,执行同样的操作,不用再创建实现类的对象,只要再创建Thread的对象就可以,参数用的依然是同一个实现类的对象。tt.start();}
}
同样 可以利用匿名内部类的方法写出   遍历100以内的奇数和偶数的俩个线程:
public class PrintNumberTest
{public static void main(String[] args){
//        EvenNumber ee = new EvenNumber();
//        OddNumber oo = new OddNumber();
//        Thread t1 = new Thread(ee);
//        Thread t2 = new Thread(oo);
//        t1.start();
//        t2.start();//匿名的Thread的子类,参数为匿名的Runnable的实现类的匿名对象。new Thread(new Runnable(){public void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}}).start();new Thread(new Runnable(){public void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 1){System.out.println(Thread.currentThread().getName() + ": " + i);}}}}).start();}
}class EvenNumber implements Runnable
{public void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
}class OddNumber implements Runnable
{@Overridepublic void run(){for (int i = 1; i <= 100; i++){if(i % 2 == 1){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
}
线程创建的俩种方式的对比:
共同点:
①启动线程,使用的都是Thread类中定义的start( )方法。
②创建的线程对象,都是Thread类或Thread的子类的实例。
不同点:
方式一是类的继承,方式二是接口的实现。
建议使用Runnable接口的方式
实现Runnable接口的方式的好处:
①一个类可以实现多个接口,避免了类的单继承的局限性。
②创建多个线程对象的构造器的参数(Runnable的实现类)可以使用同一个实现类的对象,更适合处理有共享数据的问题。
③实现了代码和数据的分离。
联系:
Thread类实现了Runnable接口。体现了代理模式。

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

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

相关文章

中国电信终端产业联盟5G Inside行业子联盟正式成立!宏电股份作为副理事单位受邀加入

11月9日&#xff0c;中国电信于广州召开“2023中国电信终端生态合作暨中国电信终端产业联盟&#xff08;以下简称CTTA&#xff09;第十四次会员大会”&#xff0c;联盟成员齐聚现场。作为CTTA大会的一个重要环节&#xff0c;中国电信终端产业联盟5G Inside行业子联盟正式成立&a…

[PyTorch][chapter 61][强化学习-免模型学习 off-policy]

前言&#xff1a; 蒙特卡罗的学习基本流程&#xff1a; Policy Evaluation : 生成动作-状态轨迹,完成价值函数的估计。 Policy Improvement: 通过价值函数估计来优化policy。 同策略&#xff08;one-policy&#xff09;&#xff1a;产生 采样轨迹的策略 和要改…

美国材料与试验协会ASTM发布新版玩具安全标准 ASTM F963-23

美国材料与试验协会ASTM发布新版玩具安全标准 ASTM F963-23 2023年10月13日&#xff0c;美国材料与试验协会&#xff08;ASTM&#xff09;发布了新版玩具安全标准ASTM F963-23 ​根据CPSIA的规定&#xff0c;当ASTM将ASTM F963的拟定修订意见通知CPSC时&#xff0c;若CPSC认为…

实战leetcode(二)

Practice makes perfect&#xff01; 实战一&#xff1a; 这里我们运用快慢指针的思想&#xff0c;我们的slow和fast都指向第一个节点&#xff0c;我们的快指针一次走两步&#xff0c;慢指针一次走一步&#xff0c;当我们的fast指针走到尾的时候&#xff0c;我们的慢指针正好…

使用Nginx和Spring Gateway为SkyWalking的增加登录认证功能

文章目录 1、使用Nginx增加认证。2、使用Spring Gateway增加认证 SkyWalking的可视化后台是没有用户认证功能的&#xff0c;默认下所有知道地址的用户都能访问&#xff0c;官网是建议通过网关增加认证。 本文介绍通过Nginx和Spring Gateway两种方式 1、使用Nginx增加认证。 生…

切换数据库的临时表空间为temp1 / 切换数据库的undo表空间为 undotbs01

目录 ​编辑 一、切换临时表空间 1、登录数据库 2、查询默认临时表空间 3、创建临时表空间temp1&#xff08;我们的目标表空间&#xff09; 4、修改默认temp表空间 5、查询用户默认临时表空间 6、命令总结&#xff1a; 二、切换数据库的undo表空间 1、查询默认undo表…

Wix使用velo添加Google ads tag并在form表单提交时向谷歌发送事件

往head里加代码时&#xff0c;不能看谷歌的代码&#xff0c;要看wix的代码&#xff0c;不然必定踩坑 https://support.wix.com/en/article/tracking-google-ads-conversions-using-wix-custom-code 这里的代码才对&#xff0c;因为wix搞了个velo&#xff0c;这个velo很傻x&am…

RK3399平台开发系列讲解(内存篇)free 命令查看内存占用情况介绍

🚀返回专栏总目录 文章目录 一、free的使用二、free的内容📢free 指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段,以及系统核心使用的缓冲区等。 一、free的使用 -b  以 Byte 为单位显示内存使用情况。-k  以 KB 为单位显示内存使用情况。…

ARM 基础学习记录 / ARM 裸机编程

汇编程序调用 C 程序详情 在 C 程序和 ARM 汇编程序之间相互调用时必须遵守 ATPCS 规则&#xff0c;其是基于 ARM 指令集和 THUMB 指令集过程调用的规范&#xff0c;规定了调用函数如何传递参数&#xff0c;被调用函数如何获取参数&#xff0c;以何种方式传递函数返回值。 寄存…

ARM 基础学习记录 / 异常与GIC介绍

GIC概念 念课本&#xff08;以下内容都是针对"通用中断控制器&#xff08;GIC&#xff09;"而言&#xff0c;直接摘录的&#xff0c;有的地方可能不符人类的理解方式&#xff09;&#xff1a; 通用中断控制器&#xff08;GIC&#xff09;架构提供了严格的规范&…

GPT-4.0网页平台-ChatYY

ChatYY的优势&#xff1a; 1. 支持大部分AI模型&#xff0c;且支持AI绘画&#xff1a; 2. 问答响应速度极快&#xff1a; 3. 代码解析&#xff1a; 4. 支持文档解读&#xff1a; 5. PC、移动端均支持&#xff1a; 访问直达&#xff1a;ChatYY.com

gird 卡片布局

场景一&#xff1a;单元格大小相等 这承载了所有 CSS Grid 中最著名的片段&#xff0c;也是有史以来最伟大的 CSS 技巧之一&#xff1a; 等宽网格响应式卡片实现 .section-content {display: grid;grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));gap: 10px; …

Jmeter+ant+jenkins接口自动化测试

平台简介 一个完整的接口自动化测试平台需要支持接口的自动执行&#xff0c;自动生成测试报告&#xff0c;以及持续集成。Jmeter 支持接口的测试&#xff0c;Ant 支持自动构建&#xff0c;而 Jenkins 支持持续集成&#xff0c;所以三者组合在一起可以构成一个功能完善的接口自动…

LeetCode(6)轮转数组【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 189. 轮转数组 1.题目 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1…

Jira Software Enterprise Crack

Jira Software Enterprise Crack Jira软件是为您的应用程序组中的每一个成员设计、监控和启动优秀软件的。 策略&#xff1a;生成用户故事和问题&#xff0c;策略冲刺&#xff0c;并在应用程序团队中分配任务。 跟踪&#xff1a;在具有绝对可见性的完整背景下&#xff0c;确定团…

DHorse(K8S的CICD平台)的实现原理

综述 首先&#xff0c;本篇文章所介绍的内容&#xff0c;已经有完整的实现&#xff0c;可以参考这里。 在微服务、DevOps和云平台流行的当下&#xff0c;使用一个高效的持续集成工具也是一个非常重要的事情。虽然市面上目前已经存在了比较成熟的自动化构建工具&#xff0c;比如…

千帆SDK开源到GitHub,开发者可免费下载使用!

目录 一、SDK的优势 二、千帆SDK&#xff1a;快速落地LLM应用 三、如何快速上手千帆SDK 1、SDK快速启动 快速安装 平台鉴权 如何获取AK/SK 以“Chat 对话”为调用示例 2. SDK进阶指引 3. 通过Langchain接入千帆SDK 为什么选择Langchain 开源社区 千帆社区 好消息&…

高德地图添加信息弹窗,信息弹窗是单独的组件

//弹窗组件 <template><el-card class"box-card" ref"boxCard" v-if"showCard"><div slot"header" class"clearfix"><div class"title">{{ model.pointName }}</div><div class…

JVM中jhat虚拟机堆转储快照分析工具

jhat虚拟机堆转储快照分析工具 1、jhat jhat也是jdk内置的工具之一。主要是用来分析java堆的命令&#xff0c;可以将堆中的对象以html的形式显示出来&#xff0c;包括对 象的数量&#xff0c;大小等等&#xff0c;并支持对象查询语言。 使用jmap等方法生成java的堆文件后&a…

时序预测 | MATLAB实现基于LSSVM-Adaboost最小二乘支持向量机结合AdaBoost时间序列预测

时序预测 | MATLAB实现基于LSSVM-Adaboost最小二乘支持向量机结合AdaBoost时间序列预测 目录 时序预测 | MATLAB实现基于LSSVM-Adaboost最小二乘支持向量机结合AdaBoost时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于LSSVM-Adaboos…