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,一经查实,立即删除!

相关文章

MATLAB算法实战应用案例精讲-【目标检测】机器视觉-工业相机参数

目录 前言 知识储备 相机镜头工作原理 算法原理 相机模型 坐标系

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

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

C# .NET6 Log4net输出日志

在 C# .NET6 开发中&#xff0c;log4net 是一个常用的日志记录框架&#xff0c;它可以帮助我们方便地输出日志信息。本教程将向你展示如何在 C# .NET6 中实现 log4net 的日志输出功能。 整体流程 下面是实现“C# .NET6 log4net 输出日志”的整体流程&#xff0c;我们将通过以下…

[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;我们的慢指针正好…

c#流程控制

c#分支语句 namespace ConsoleApp1 {internal class Program{static void Main(string[] args){Console.WriteLine("请输入学生成绩");string sConsole.ReadLine();int aint.Parse(s);//将字符类型强制转换为int类型if (a > 90){ Console.WriteLine("成绩优…

使用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表…

电脑本地安装宝塔/docker 安装宝塔

一、先去docker官网(http://docker.com)下载软件并进行安装&#xff0c;网站打不开多试几次或者找梯子。 二、macos系统里按“command 空格”搜索“终端”回车&#xff0c;启动终端程序。 三、执行下面命令&#xff0c;拉取docker镜像。 docker pull pch18/baota:clear pch…

更换Master

Kubernetes 1.28 版本中更换节点需要以下步骤&#xff1a; 准备新节点 首先&#xff0c;需要准备好新节点&#xff0c;确保其满足 Kubernetes 集群的硬件和软件要求。具体要求可以参考 Kubernetes 官方文档。 添加新节点到集群 使用 kubectl join 命令将新节点添加到集群。…

HBase导出建表语句

HBase导出建表语句 HBase是一个面向大数据的分布式列存数据库&#xff0c;它以Hadoop作为底层存储和计算平台。在HBase中&#xff0c;数据以表的形式存储&#xff0c;每个表由行和列组成。本文将介绍如何使用HBase导出建表语句&#xff0c;并提供相应的代码示例。 HBase建表语…

使用spark进行递归的可行方案

在实际工作中会遇到&#xff0c;最近有需求将产品炸开bom到底层&#xff0c;但是ERP中bom数据在一张表中递归存储的&#xff0c;不循环展开&#xff0c;是无法知道最底层原材料是什么。 在ERP中使用pl/sql甚至sql是可以进行炸BOM的&#xff0c;但是怎么使用spark展开&#xff0…

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;以何种方式传递函数返回值。 寄存…

Mybatis的代码生成工具

SSM中使用步骤 1、在 pom.xml 添加插件 pom.xml <!-- build-plugins下 --> <plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><config…

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; …