Java多线程--对比创建多线程的两种方式

news2024/11/16 17:38:23

文章目录

  • 一、对比两种方式
    • (1)对比
    • (2)Runnable的好处
      • 1、案例1
      • 2、案例2
    • (3)区别和联系
    • (4)补充说明
  • 二、笔试题
    • (1)题1
    • (2)题2

一、对比两种方式

(1)对比

<1> 两种方式步骤如下:

方式一:继承Thread
image.png

方式二:实现Runnable接口
image.png

<2> 演示代码:计算大于某一规定值的质数的线程

①方式一:继承Thread类

将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。

class PrimeThread extends Thread {
   	//1.创建类PrimeThread继承Thread
         long minPrime;	//属性
         PrimeThread(long minPrime) {
   	//给指定数赋值
             this.minPrime = minPrime;
         }
 
         public void run() {
   	//2.重写run方法
             // compute primes larger than minPrime
              . . .
         }
     }
 
--------------------------------------------------------------------------------

然后,下列代码会创建并启动一个线程: 
     PrimeThread p = new PrimeThread(143);	//3.创建当前类PrimeThread的对象
     p.start();	//4.用对象去调用start()方法,调用start()方法的时候,实际上调用的是run方法,run方法里面写的是这个线程要做什么事情

②方式二:实现Runnable接口

创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

class PrimeRun implements Runnable {
   	//1、声明类PrimeRun实现Runnable接口
         long minPrime;	
         PrimeRun(long minPrime) {
   	//通过构造器赋值指定数
             this.minPrime = minPrime;
         }
 
         public void run() {
   	//2、计算比指定数大的质数都有哪些(逻辑代码)
             // compute primes larger than minPrime 
              . . .
         }
     }
 
//--------------------------------------------------------------------------------

//然后,下列代码会创建并启动一个线程: 
     PrimeRun p = new PrimeRun(143);	//3、创建实现类的对象
     new Thread(p).start();	//4、把对象作为参数传递到Thread类的构造器中,造一个线程的对象,调用start()方法

🍰对比两种方式

  • 共同点:
    • 启动线程,使用的都是Thread类中定义的start()
    • 创建的线程对象,都是Thread类(方式二)或其子类(方式一)的实例。
    • 方式一覆盖的是Thread里面的run()方法,方式二覆盖的是Runnable里面的run()方法。
  • 不同点:
    • 一个是类的继承,一个是接口的实现

(2)Runnable的好处

☕对于Runnable

建议:建议使用实现Runnable接口的方式。

🍰实现Runnable接口比继承Thread类所具有的优势Runnable方式的好处):

① 实现的方式,避免的类的单继承的局限性

② 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。更适合处理有共享数据的问题。(见下面案例)

③ 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。实现了代码和数据的分离

比如上面的例子中,p可以作为一个共享数据传递到各个线程当中,将共享的数据封装到p里面,如下:

image.png

具体调用start()方法,start()调run(),就是具体要处理的代码逻辑,所以代码逻辑和数据分离了,如下:

image.png

现在的逻辑很简单,以后的数据会放到相应的数据库当中,或者在程序当中会以配置文件的方式去存放一些数据。

代码就是相应的逻辑,可以去读配置文件中的数据,然后在程序当中去运行。

配置文件中的数据后面还可以修改,程序不用变,还是去读文件。

1、案例1

比如前面举过的一个例子:

public class EvenNumberTest2 {
   
    public static void main(String[] args) {
   
        //3.创建当前实现类的对象
        EvenNumberPrint p=new EvenNumberPrint();

        //4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread t1=new Thread(p);

        //5.通过Thread类的实例调用start()
        t1.start();


        //main()方法对应的主线程执行的操作
        for (int i = 1; i <= 100; i++) {
   
            if (i%2==0) {
   
                System.out.println(Thread.currentThread().getName() + ":" + i); //方便查看线程
            }
        }


        /*
        * 再创建一个线程,用于遍历100以内的偶数
        * */
        Thread t2=new Thread(p);
        t2.start();

    }
}

//1.创建一个实现Runnable接口的类(实现类)
class EvenNumberPrint implements Runnable {
   
    //2.实现接口中的抽象方法run()方法 -->将此线程要执行的操作,声明在此方法体中
    @Override
    public void run() {
   
        //创建分线程遍历100以内的偶数
        for (int i = 1; i <= 100; i++) {
   
            if (i%2==0) {
   
                System.out.println(Thread.currentThread().getName() + ":" + i); //方便查看线程
            }
        }
    }
}

这里又创建了一个线程,让它遍历100以内的偶数。就是t2。

可以发现,我们并没有再去创建一个实现类的对象,虽然是两个线程,但是用的是同一个p。如下:

image.png

这个p就可以看作是这两个线程的共享数据。因为此时这两个线程共用这一个p。


2、案例2

①方式二实现Runnable接口里面

现在类EvenNumberPrint实现了接口Runnable,假设现在有一个double类型的money,如下代码:

package yuyi01.thread;

public class EvenNumberTest2 

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

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

相关文章

uniapp 用css animation做的鲤鱼跃龙门小游戏

第一次做这种小游戏&#xff0c;刚开始任务下来我心里是没底的&#xff0c;因为我就一个‘拍黄片’的&#xff0c;我那会玩前端的动画啊&#xff0c;后面尝试写了半天&#xff0c;当即我就给我领导说&#xff0c;你把我工资加上去&#xff0c;我一个星期给你做出来&#xff0c;…

Idea 连接 mysql 数据库

前言 为了方便直接在 idea 开发工具中直接使用数据库&#xff0c;如查看数据等&#xff0c;可以在 idea 中配置数据库相关属性&#xff0c;实现操作数据库。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 使用步骤 点击最右面的 database&#xff0…

手把手系列!无需 OpenAI 即可搭建 RAG 应用

OpenAI 是时下最火爆的大语言模型&#xff08;LLM&#xff09;&#xff0c;不过除了 OpenAI 以外&#xff0c;还有许多不同的 LLM。此前&#xff0c;我们发布的许多篇文章中都介绍了如何使用 LangChain、Milvus 和 OpenAI 搭建众多 RAG 应用&#xff0c;这次我们来试试不一样的…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏1(附项目源码)

本篇最终效果演示 文章目录 本篇最终效果演示系列目录前言环境素材绘制地形 实现人物移动指示显示物品名称源码完结 系列目录 【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏1&#xff08;附项目源码&#xff09; 【制作100个unity游戏之23】实现类似七日杀、森…

在FreeRTOS上使用软定时器的ESP32开发指南

在FreeRTOS上使用软定时器的ESP32开发指南 在ESP32的开发中&#xff0c;使用FreeRTOS实时操作系统可以有效地提高多任务处理和系统稳定性。其中&#xff0c;软定时器是一项非常有用的功能&#xff0c;它可以让我们在系统中创建定时任务&#xff0c;而无需硬件定时器的支持。 …

基于cubeMX的正点原子miniSTM32对W25Q64的存储使用

一、实现目标 使用cubeMX建立项目工程&#xff0c;结合正点原子提供的hal库对W25Q64闪存调用的例程&#xff0c;实现W25Q64的读写。 二、实现过程 1、首先建立cubeMX工程&#xff0c;其他项设置不再叙述&#xff0c;只看连接W25Q64的SPI设置&#xff0c;这里使用SPI1&#xf…

css display 左右对齐 技巧

.list_number{ display: flex; } .list_name_number{ width:100px; } //左边固定width .list_name_type{ //右边给flex:2 自动撑开 flex:2; }

docker(上)

笔记资料参考与尚硅谷 前提知识课程介绍课程定位学习建议 1前提知识 boot cloud git push pull redis nginx mysql... Linux centos ubuntu 2课程介绍 2.1 2018 vs 2022 2.2 k8s&#xff08;雷峰崖&#xff09; 2.3 大纲 3课程定位&#xff08;因材施教量体裁衣…

Web08--JavaScript高级

1、BOM对象 BOM&#xff1a;browser object model 浏览器对象模型 BOM对象包括window对象、screen对象、history对象、location对象、navigator对象。 1.1 window对象 所有的浏览器都支持window对象。它表示的浏览器窗口 window对象是js中的顶层对象&#xff0c;所有的j…

DOS经典软件,落下帷幕,国产新一代中文编程体系兴起

互联网的演变犹如狂风巨浪&#xff0c;一些我们以为早已遗忘的软件却深深烙印在心底&#xff0c;特别是对于那些经历了DOS到Windows时代变革的人们来说&#xff0c;这种感觉尤为强烈。 DOS软件&#xff0c;曾是80后青春岁月中的璀璨星辰&#xff0c;如今虽已成为历史的遗迹&am…

Redis内存空间节省小技巧

背景&#xff1a;为提升会员对当前等级的权益感知&#xff0c;需对用户仍未领取的权益进行弹框或消息位置推荐&#xff0c;会员需推荐权益有10项&#xff0c;且项权益均需需校验当日推荐次数并做推送限制&#xff0c;推荐次数记入Redis缓存&#xff0c;会员数据庞大&#xff0c…

[实战]加密传输数据解密

前言 下面将分享一些实际的渗透测试经验&#xff0c;帮助你应对在测试中遇到的数据包内容加密的情况。我们将以实战为主&#xff0c;技巧为辅&#xff0c;进入逆向的大门。 技巧 开局先讲一下技巧&#xff0c;掌握好了技巧&#xff0c;方便逆向的时候可以更加快速的找到关键函数…

代码随想录 Leetcode226.翻转二叉树

题目&#xff1a; 代码(首刷看解析 2024年1月25日&#xff09;&#xff1a; class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root nullptr) return root;swap(root->left,root->right);invertTree(root->left);invertTree(root->right);retu…

Java面试提纲

JDK 1 jdk1.8版本后的新特性有哪些? Java Development Kit (JDK) 1.8&#xff08;也称为Java 8&#xff09;在2014年3月发布&#xff0c;引入了许多重要的新特性&#xff0c;以下是其中的一些关键特性&#xff1a; Lambda表达式&#xff1a; Java 8引入了lambda表达式&#x…

java大数据hadoop2.9.2 Linux安装mariadb和hive

一、安装mariadb 版本centos7 1、检查Linux服务器是否已安装mariadb yum list installed mariadb* 2、如果安装了&#xff0c;想要卸载 yum remove mariadb rm -rf /etc/my.cnf rm -rf /var/lib/mysql 才能完全删除 3、安装mariadb 在线网络安装 yum install -y mari…

java常见的面试问题

目录 一、异常 1、 throw 和 throws 的区别&#xff1f; 2、 final、finally、finalize 有什么区别&#xff1f; 3、try-catch-finally 中哪个部分可以省略&#xff1f; 4、try-catch-finally 中&#xff0c;如果 catch 中 return 了&#xff0c;finally 还会执行吗&#…

vue3 实现自定义radio

需求背景解决效果bgRadio.vue 需求背景 实现一个自定义选中样式的 radio 解决效果 bgRadio.vue <!--/** * author: liuk * date: 2024/01/25 * describe: 背景单选框 * email: 1229223630qq.com */--> <template><div class"radio-wrap"><l…

Linux 互斥锁、读写锁、条件变量以及信号量

互斥锁 同步与互斥概述 现代操作系统基本都是多任务操作系统&#xff0c;即同时有大量可调度实体在运行。在多任务操作系统中&#xff0c;同时运行的多个任务可能&#xff1a; 都需要访问/使用同一种资源多个任务之间有依赖关系&#xff0c;某个任务的运行依赖于另一个任务 …

AP5216 平均电流型LED降压恒流驱动IC 手电筒汽车摩托车灯芯片

产品描述 AP5216 是一款 PWM工作模式, 高效率、外围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高精度降压 LED 恒流驱动芯片。输出最大功率可达9W&#xff0c;最大电流 1.0A。AP5216 可实现全亮/半亮功能切换&#xff0c;通过MODE 切换&#xff1a;全亮/半亮…

Java 集合Map相关面试题

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…