【Java】创建多线程的四种方式

news2024/11/18 5:30:01

一、方式1:继承Thread类

步骤:

  1. 创建一个继承于Thread类的子类
  2. 重写Thread类的run()方法 ----> 此线程执行的操作声明在方法体中
  3. 创建当前Thread子类的对象
  4. 通过实例对象调用start()方法,启动线程 ----> Java虚拟机会调用run()方法

注意main()方法是主线程

1. 创建线程:

//自定义线程类
public class MyThread extends Thread {

	// 共享数据要放在run()方法外边才能被共享且声明为static,否则就是每个线程都会调用run()方法,都会单独拥有一个run()方法里的独享数据,而非共享数据
	//eg: static int trick = 100;
    //定义指定线程名称的构造方法
    public MyThread(String name) {
        //调用父类的String参数的构造方法,指定线程的名称
        super(name);
    }
    /**
     * 重写run方法,完成该线程执行的逻辑
     */
    @Override
    public void run() {
        // 执行的操作
    }
}

2. 调用线程:

public class TestMyThread {
    public static void main(String[] args) {
        //创建自定义线程对象1
        MyThread mt1 = new MyThread("子线程1");
        //开启子线程1
        mt1.start();
        
        //创建自定义线程对象2,分别创建对象开启线程,不可以数据共享,若要共享需要创建static变量
        MyThread mt2 = new MyThread("子线程2");
        //开启子线程2
        mt2.start();
    }
}

3. 创建Thread类的匿名子类的匿名对象

// 创建Thread类的匿名子类的匿名对象,并启动线程
new Thread(){
	public void run(){
		// 执行的操作
	}
}.strat(); // 启动线程

二、方式2:实现Runnable接口

  1. 创建一个实现Runnable接口的类
  2. 实现接口中的run()方法 ----> 线程执行的操作声明在此方法中
  3. 创建实例对象
  4. 将此对象作为参数传到Thread类的构造器中,创建Thread类的实例
  5. 通过Thread的实例对象调用strat()方法,启动线程 ----> Java虚拟机会调用run()方法

最终还是通过Thread实现的

1. 创建线程:

public class MyRunnable implements Runnable {

	// 共享数据要放在run()方法外边才能被共享,否则就是每个线程都会调用run()方法,都会单独拥有一个run()方法里的独享数据,而非共享数据
	//eg: int trick = 100;
    @Override
    public void run() {
        // 执行的操作
    }
}

2. 调用线程

public class TestMyRunnable {
    public static void main(String[] args) {
        //创建自定义类对象  线程任务对象
        MyRunnable mr = new MyRunnable();
        //创建线程对象1
        Thread t1 = new Thread(mr, "长江1");
        t1.start();

		//创建线程对象2,注意两个线程传入的是同一个对象,可以实现数据共享
        Thread t2 = new Thread(mr, "长江2");
        t2.start();
    }
}

3. 创建Runnable接口的匿名子类的匿名对象

new Thread(new Runnable(){
	public run(){
		// 执行的操作
	}
}).start(); // 开启线程

三、继承Thread类 VS 实现Runnable接口

1. 共同点:

  • 都是通过Thread类中定义的start()来启动线程。
  • 都是通过Thread类或其子类的实例对象来创建线程。

2. 不同点:

  • Thread是继承
  • Runnable是实现

3. Runnable好处:

  • 通过实现的方式,避免了类的单继承的局限性
  • 自动共享数据,更适合处理有共享数据的业务逻辑
  • 实现了逻辑代码(在run()方法中)和数据(在创建线程的方法中)的分离

四、Thread类常用方法和生命周期

1. 构造器

构造器描述
public Thread()分配一个新的线程对象。
public Thread(String name)分配一个指定名字的新的线程对象。
public Thread(Runnable target)指定创建线程的目标对象,它实现了Runnable接口中的run方法
public Thread(Runnable target,String name)分配一个带有指定目标新的线程对象并指定名字。

2. 常用方法——线程设置

构造器描述
public void run()此线程要执行的任务在此处定义代码。
public void start()导致此线程开始执行; Java虚拟机调用此线程的run方法。
public String getName()获取当前线程名称。
public void setName(String name)设置该线程名称。
public static Thread currentThread()返回对当前正在执行的线程对象的引用。在Thread子类中就是this,通常用于主线程和Runnable实现类
public static void sleep(long millis)使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
public static void yield()主动释放当前线程的执行权,一旦执行,就释放CPU的执行权,yield只是让当前线程暂停一下,让系统的线程调度器重新调度一次,希望优先级与当前线程相同或更高的其他线程能够获得执行机会,但是这个不能保证,完全有可能的情况是,当某个线程调用了yield方法暂停之后,线程调度器又将其调度出来重新执行。

3. 常用方法——阻塞线程

构造器描述
public final boolean isAlive()测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。
void join()阻塞其他线程,在线程a中通过线程b调用join(),意味着线程a进入阻塞状态,直到线程b执行结束,线程a才结束阻塞状态。等待该线程终止。
void join(long millis)阻塞其他线程,阻塞其他线程的时间最长为 millis 毫秒。如果millis时间到,将不再等待。
void join(long millis, int nanos)阻塞其他线程,阻塞其他线程的时间最长为 millis 毫秒 + nanos 纳秒。
public final void stop()已过时,不建议使用。强行结束一个线程的执行,直接进入死亡状态。run()即刻停止,可能会导致一些清理性的工作得不到完成,如文件,数据库等的关闭。同时,会立即释放该线程所持有的所有的锁,导致数据得不到同步的处理,出现数据不一致的问题。
void suspend() / void resume()这两个操作就好比播放器的暂停和恢复。二者必须成对出现,否则非常容易发生死锁。suspend()调用会导致线程暂停,但不会释放任何锁资源,导致其它线程都无法访问被它占用的锁,直到调用resume()。已过时,不建议使用。

4. 常用方法——优先级

每个线程都有一定的优先级,同优先级线程组成先进先出队列(先到先服务),使用分时调度策略。优先级高的线程采用抢占式策略,获得较多的执行机会。每个线程默认的优先级都与创建它的父线程具有相同的优先级。

构造器描述
MAX_PRIORITY(10)三个优先级常量之一最高优先级
MIN _PRIORITY (1)三个优先级常量之一最低优先级
NORM_PRIORITY (5)三个优先级常量之一普通优先级,默认情况下main线程具有普通优先级。
public final int getPriority()返回线程优先级
public final void setPriority(int newPriority)改变线程的优先级,范围在[1,10]之间。

5. 线程的生命周期

jdk1.5 之前的5种状态:
在这里插入图片描述
jdk1.5 之后的6种状态:

  • 将准备和运行合并为一个Runnable状态
  • 将阻塞细分为:计时等待、锁阻塞、无线等待3种状态
    在这里插入图片描述

五、解决线程的安全问题

当多个线程同时操作同一个共享数据时,就会出现线程的安全问题。

方式一:同步代码块

/**
*	1.同步监视器,俗称锁。哪个线程获得了锁,哪个线程就能执行该代码块
*	2.同步监视器可以是任何一个类的对象。但是,多个线程必须共用同一个同步监视器,且该对象是唯一的(只有一个实例对象)。
*		>可以自定义一个专用于线程锁的类,然后在这里创建对象作为锁使用。
*		>可以使用this充当锁,this指向当前对象。但是要注意当前类是否只创建了一个对象(保证唯一性)
*			>在继承Thread的方式中不可以使用this,因为每一个线程都需要创建对象,不满足唯一性
*			>在继承Thread的方式中,创建对象作为锁也需要声明为static的才可以,static Object obj = new Pbject();
*			>可以使用“当前类.class”充当锁。因为“Class clz = 类.class”是一个类,仅加载一次,是全局唯一的(反射),该方式在实现Runnable中也可以使用
*	
*/
synchronized(同步监视器){
	// 需要被同步的代码,即操作共享数据的代码
}

方式二:同步方法

/*
*用synchronized 直接修饰操作同步代码的方法
*	1.在非static的方法中,默认锁是:this。锁无法修改,因而在继承Thread方法中不适用,可以改成同步代码块方式,手动添加将当前类做为锁
*	2.在static的方法中,默认的锁是:当前类.class。即当前类本身。
*	
*/
// 示例代码:在run()方法中调用show()方法
public synchronized void show(){
	// 操作共享数据的代码
}

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

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

相关文章

QuickHMI Hawk R3 Crack

基于网络的 SCADA / HMI 系统 QuickHMI Hawk R3 QuickHMI是一个 100% 基于网络的SCADA/HMI 系统。 得益于HTML5、SVG和Javascript等现代网络技术,可视化可以在任何当前浏览器和设备中显示。作为浏览器的替代品,可以使用“独立查看器”和移动应用程序。 Q…

react react-redux学习记录

react react-redux学习记录1.原理2.怎么用呢2.1 容器组件2.2UI组件2.3 App.jsx3.简化3.1简写mapDispatch3.2 Provider组件的使用3.3整合UI组件和容器组件1.原理 UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。 容器组件:负责和redux通信&…

Orcad原理图放置辅助线的方法

Orcad原理图放置辅助线的方法 设计当中,可以通过放置辅助线来标识信号方向或者对功能模块进行分块标识。 1)执行菜单命令“Place-Line”(快捷键“ShiftL”),激活放置状态。 2)在一个合适的位置单击鼠标左键…

零基础该如何转行Python工程师?学习路线是什么?

最近1年的主要学习时间,都投资到了 python 数据分析和数据挖掘上面来了,虽然经验并不是十分丰富,但希望也能把自己的经验分享下,最近也好多朋友给我留言,和我聊天,问我python该如何学习,才能少走…

字节前端必会面试题(持续更新中)

事件传播机制(事件流) 冒泡和捕获 谈一谈HTTP数据传输 大概遇到的情况就分为定长数据 与 不定长数据的处理吧。 定长数据 对于定长的数据包而言,发送端在发送数据的过程中,需要设置Content-Length,来指明发送数据的长度。 当…

前端面试题——性能优化 高频

目录 一、CDN的概念 二、CDN的原理 三、懒加载的实现原理 四、对节流与防抖的理解 五、实现节流函数和防抖函数 六、回流与重绘的概念及触发条件 七、如何避免回流与重绘? 八、如何对项目中的图片进行优化? 九、如何⽤webpack来优化前端性能&…

Python 简单可变、复杂可变、简单不可变、复杂不可变类型的copy、deepcopy的行为

copy模块:copy:浅拷贝deepcopy:深拷贝简单可变类型、复杂可变的copy()、deepcopy():简单不可变、复杂不可变类型的copy()、deepcopy():结论:对于简单类型的可变类型copy是深拷贝,改变了该拷贝变…

1.FFmpeg-音视频基础

专栏介绍基于最新的FFmpeg5.1.2版本讲解学习, 跟随博主一起学习ffmpeg: 本专栏学习流程为: FFmpeg安装、

Spring之AOP理解及使用

文章目录AOP是什么AOPSpring的通知类型1.Before通知2. AfterReturning通知3.AfterThrowing通知4. After通知5. Around通知动态代理JDK动态代理CGLib动态代理动态代理的代码展示AOP使用切面类的配置最后大家好,我是Leo!今天给大家带来的是关于Spring AOP的…

jsp学生成果管理系Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 学生成果管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0…

分布式理论-学习笔记

1 分布式概述 分布式系统是计算机程序的集合,这些程序利用跨多个独立计算节点的计算资源来实现共同的目标。可以分为分布式计算、分布式存储、分布式数据库等。 2 系统模型 2.1 故障模型 Byzantine failure:节点可以任意篡改发送给其他节点的数据ADB:Byzantine fa…

Stacked hourglass networks for human pose estimation代码学习

Stacked hourglass networks for human pose estimation https://github.com/princeton-vl/pytorch_stacked_hourglass 这是一个用于人体姿态估计的模型,只能检测单个人 作者通过重复的bottom-up(高分辨率->低分辨率)和top-down&#xff0…

乐友商城学习笔记(十五)

无状态登陆原理 在服务器端保存session 无状态不需要session,把登陆状态保存在cookie中 jwtrsa token:登陆时, jwt oath2 jwt:头信息(jwt) 载荷(用户信息,签发人,签发时…

设备驱动模型--存储技术原理分析笔记 基于2.6.43内核

本文为读书笔记,详细内容参考《存储原理技术分析》1- 驱动模型2- 总线类型2.1- 重要数据结构总线bus_type 和 bus_type_private 互相可以找到对方struct bus_type {const char *name;struct bus_attribute *bus_attrs;struct device_attribute *dev_attrs;s…

2023软件测试工程师全新技术栈,吃透这些,起薪就是25k~

相信每个准备软件测试面试的同学,不管你是大学刚毕业,满心憧憬着进入公司实习、非计算机行业转行软件测试、自学测试就业还是培训后就业,都会面临着众多的疑问和不解,那就是该怎么走出着第一步,今天本文一次性告诉你&a…

MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU FLASH

MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU 32BIT 256KB FLASH 144LQFP【说明】Kinetis K6x MCU系列是一个可扩展的组合,具有不同级别的集成,提供丰富的模拟、通信、定时和控制外设套件,以适应广泛的需求。应用楼宇自动化控制器人…

ARM中的寄存器

ARM工作模式 ARM有8个基本的工作模式 User 非特权模式,一般在执行上层的应用程序时ARM处于该模式FIQ 当一个高优先级中断产生后ARM将进入这种模式IRQ 当一个低优先级中断产生后ARM将进入这种模式SVC 当复位或执行软中断指令后ARM将进入这种模式Abort 当产生存取异常…

Linux 红帽9.0 本地源 与 网络源 搭建

本次我们使用的是 redhat 9.0 版本,是redhat 的最新版本,我们一起来对其进行 本地仓库 和 网络仓库的搭建部署~!!关于 本地仓库( 本地源 ),和 网络仓库 ( 网络源 )&#…

【项目实战】从0开始入门JDK源码 - LinkedList源码

一、源码位置 一般来说IDEA配置好JDK以后 ,JDK的源码其实也配置好了,本文是基于JDK1.8的源码说明 rt - java - util - LinkedList 二、 继承关系图 LinkedList public class LinkedList<E>extends AbstractSequentialList<E>implements

【计算机网络基础】

计算机网络基础网络的基本概念网络互联网IP地址MAC地址网络协议网络分层模型网络应用程序的通信流程网络的基本概念 网络 网络是由若干结点和链接这些结点的链路组成&#xff0c;网络中的结点可以是计算机&#xff0c;交换机&#xff0c;路由器等设备 网络设备&#xff1a;交…