【java学习—十五】创建多线程的两种方式(2)

news2024/11/24 14:13:17

文章目录

  • 1. 多线程的创建和启动
  • 2. Thread 类
  • 3. 创建多线程的两种方式
    • 3.1.继承Thread类实现多线程
      • 3.1.1. 举例
      • 3.1.2. 举例2
    • 3.2. 实现Runnable接口
    • 3.2.1. 举例1
    • 3.2.2. 举例2
  • 4. 继承方式和实现方式的联系与区别
  • 5. 使用多线程的优点


1. 多线程的创建和启动

Java 语言的 JVM 允许程序运行多个线程,它通过 java.lang.Thread类来实现。
Thread类的特性
    每个线程都是通过某个特定 Thread 对象的 run() 方法来完成操作的,经常把 run() 方法的主体称为线程体;
    通过该 Thread 对象的 start() 方法来调用这个线程

run():想要在开启的多线程中运行的代码逻辑,就写到run方法里
start():用来启动线程,本质上就是开始运行run方法

2. Thread 类

构造方法
    Thread():创建新的 Thread 对象
    Thread(String threadname):创建线程并指定线程实例名

    Thread(Runnable target):指定创建线程的目标对象,它实现了 Runnable接口中的 run 方法
    Thread(Runnable target, String name):创建新的 Thread 对象

3. 创建多线程的两种方式

3.1.继承Thread类实现多线程

步骤:
(1)定义子类继承 Thread 类。
(2)子类中重写 Thread 类中的 run 方法。
(3)创建 Thread 子类对象,即创建了线程对象。
(4)调用线程对象 start 方法:启动线程,调用 run 方法。

3.1.1. 举例

子类TestThread继承Thread类

package day15;
/**
 * 继承Thread的方式实现多线程
 * @author 14532
 *
 */
public class TestThread extends Thread{
	@Override
	public void run() {
		System.out.println("多线程运行的代码");
		for(int i = 0; i <5; i++) {
			System.out.println("这是多线程的逻辑代码:" + i);
		}
	}

}

Test.java

package day15;

public class Test {
	public static void main(String[] args) {
		Thread t0 = new TestThread();
		
		t0.start();//启动线程
		System.out.println("--------------1------------");
		System.out.println("--------------2------------");
		System.out.println("--------------3------------");
		
		/**
		 * 多次运行这个main方法之后
		 * 我们发现main方法中打印的3行与开启线程运行run方法中的打印语句是混合起来的
		 * 而且main方法中的打印与run方法中打印语句顺序是不固定的
		 * 为什么?
		 * 因为main执行t0.start()方法开启多线程之后,就相当于在main方法之外开启一个支流
		 * 这个时候t0.start()的之后的main方法的其他代码的运行就与run方法运行无关了
		 * 
		 * 以当前代码为例
		 * t0.start()的之后的main方法的其他代码与run方法的代码并行运行
		 * 就像两条河流一样,各走各的
		 * 那么控制台输出的结果就是两条并行程序运行的结果的总和,这个结果需要拆成两部分看
		 * 就可以看到,各自保持自己的输出顺序
		 * 这个就是多线程的异步,这个异步相对于执行t0.start()主程序来说的
		 * 简单来说就是开启了线程之后run方法中运行的代码和主程序中t0.start()之后的程序是并行执行的,没有先后关系
		 */
	}
}

运行结果:(注意每次运行的结果未必相同)

结果1:
在这里插入图片描述

结果2:

在这里插入图片描述

3.1.2. 举例2

注意:Test.java可以开启多个线程,比如再创建 t1、t2 两个线程

package day15;

public class Test {
	public static void main(String[] args) {
		Thread t0 = new TestThread();
		t0.start();//启动线程

		Thread t1 = new TestThread();
		t1.start();
		
		Thread t2 = new TestThread();
		t2.start();
		
		System.out.println("--------------1------------");
		System.out.println("--------------2------------");
		System.out.println("--------------3------------");
		
	}
}

运行结果:(其中一种结果)

在这里插入图片描述

3.2. 实现Runnable接口

步骤:

(1)定义子类,实现 Runnable 接口。
(2)子类中重写 Runnable 接口中的 run 方法。
(3)通过 Thread 类含参构造器创建线程对象。
(4)将 Runnable 接口的子类对象作为实际参数传递给Thread 类的构造方法中。
(5)调用 Thread 类的 start 方法:开启线程,调用Runnable 子类接口的 run 方法。

3.2.1. 举例1

new Thread(new TestRunnable());

子类实现 Runnable 接口,重写 Runnable 接口中的 run 方法

package day15;
/**
 * 通过实现Runnable接口方式实现多线程
 * @author 14532
 *
 */
public class TestRunnable implements Runnable{
	@Override
	public void run() {
		System.out.println("Runable多线程运行的代码");
		for(int i = 0; i <5; i++) {
			System.out.println("这是Runable多线程的逻辑代码:" + i);
		}
	}
}

Test.java

package day15;

public class Test {
	public static void main(String[] args) {
				
		Thread t3 = new Thread(new TestRunnable());
		t3.start();				
		
		System.out.println("--------------1------------");
		System.out.println("--------------2------------");
		System.out.println("--------------3------------");
		
	}
}

运行结果:(注意每次运行的结果未必相同)
结果1:
在这里插入图片描述

结果2:

在这里插入图片描述

3.2.2. 举例2

Thread t4 = new Thread(new TestRunnable(), "t-1");

子类实现 Runnable 接口,重写 Runnable 接口中的 run 方法

package day15;
/**
 * 通过实现Runnable接口方式实现多线程
 * @author 14532
 *
 */
public class TestRunnable implements Runnable{
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ":Runable多线程运行的代码");
		for(int i = 0; i <5; i++) {
			System.out.println(Thread.currentThread().getName() + ":这是Runable多线程的逻辑代码:" + i);
		}
	}
	
}

Test.java

package day15;

public class Test {
	public static void main(String[] args) {
		

		Thread t4 = new Thread(new TestRunnable(), "t-1");
		t4.start();
		
		Thread t5 = new Thread(new TestRunnable(), "t-2");
		t5.start();
		
		System.out.println("--------------1------------");
		System.out.println("--------------2------------");
		System.out.println("--------------3------------");
		
	}
}

运行结果:

在这里插入图片描述

结果2:

在这里插入图片描述

使用new Thread(new TestRunnable(), "t-1")这种方法能后知道运行的是哪一种线程。

4. 继承方式和实现方式的联系与区别

    
区别:

  • 继承 Thread: 线程代码存放 Thread 子类 run 方法中。重写 run 方法
  • 实现 Runnable :线程代码存在接口的子类的 run 方法。实现 run 方法

实现接口方式的好处:

  • 避免了单继承的局限性;
  • 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

注:一般使用实现接口方式来实现多线程

举例:

package day15;
/**
 * 通过实现Runnable接口方式实现多线程
 * @author 14532
 *
 */
public class TestRunnable implements Runnable{
	
	int count = 0;
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ":Runable多线程运行的代码");
		for(int i = 0; i <5; i++) {
			count++;
			System.out.println(Thread.currentThread().getName() + ":这是Runable多线程的逻辑代码:" + count);
		}
	}
	
}

Test.java

package day15;

public class Test {
	public static void main(String[] args) {
		
		
		Runnable run = new TestRunnable();
		
		Thread t4 = new Thread(run, "t-1");
		t4.start();
		
		Thread t5 = new Thread(run, "t-2");
		t5.start();
		
		
		
		System.out.println("--------------1------------");
		System.out.println("--------------2------------");
		System.out.println("--------------3------------");
		
	}
}

运行结果(其中一种):

在这里插入图片描述

5. 使用多线程的优点

多线程程序的优点:
    ①提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
    ②提高计算机系统 CPU 的利用率。
    ③改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改。(解释如下)

如果在一个方法里有1000行代码,前300行、中间300行、后400行这三段代码没有因果关系,这种情况我们就可以使用线程处理,把前中后三段代码分别放在不同线程中去运行,这样三段代码就是并行运行的。

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

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

相关文章

【差分演化算法相关文献总结】

差分演化算法相关文献总结 前言概述文献综述总结 前言 本人作为一名从事了三年演化算法研究的菜鸡研究生&#xff0c;其中大部分时间都在专注于差分演化算法&#xff08;Differential Evolution, DE&#xff09;的相关研究。现如今已经毕业&#xff0c;回顾往昔&#xff0c;经过…

跌破1940后金价直指1900 对黄金代理是好是坏?

受以鲍威尔为首的美联储官员近期讲话的影响&#xff0c;加上巴以冲突暂时出现降温&#xff0c;导致避险需求下降&#xff0c;在两大因素的影响之下&#xff0c;现货黄金行情在近期的大涨之后出现大跌。金价不光跌破1950关口&#xff0c;在跌穿1940后势头更是直指1900。金价在一…

虹科干货丨Lambda数据架构和Kappa数据架构——构建现代数据架构

文章来源&#xff1a;虹科云科技 虹科干货丨Lambda数据架构和Kappa数据架构——构建现代数据架构 如何更好地构建我们的数据处理架构&#xff0c;如何对IT系统中的遗留问题进行现代化改造并将其转变为现代数据架构&#xff1f;该怎么为你的需求匹配最适合的架构设计呢&#xf…

异常--Java

cry…catch使用 /*需求&#xff1a;测试除法器&#xff08;try...catch&#xff09;* 测试人&#xff1a;小王* 测试日期&#xff1a;2023/11/15* */ package yichang_test1;import java.util.InputMismatchException; import java.util.Scanner;public class TestException2 …

cadence virtuoso layout 无法跑DRC

问题&#xff1a;无法跑DRC could not establish connection with Calibre Interactiveon socket localhost 7000. 尝试&#xff1a; 点击一下红框右边的connect。 &#xff08;此法不一定有用&#xff0c;死马当活马医&#xff09;

Page分页records有数据,但是total=0,解决办法

Page分页records有数据&#xff0c;但是total0&#xff0c;解决办法 问题&#xff1a;程序运行起来后&#xff0c;后端接收前端传来的搜索请求信息正常&#xff0c;但无法在前端正确反馈信息&#xff0c;通过在后端排查发现total一直等于零&#xff0c;但数据库中有数据&#x…

大数据-之LibrA数据库系统告警处理(ALM-12046 网络写包丢包率超过阈值)

告警解释 系统每30秒周期性检测网络写包丢包率&#xff0c;并把实际丢包率和阈值&#xff08;系统默认阈值0.5%&#xff09;进行比较&#xff0c;当检测到网络写包丢包率连续多次&#xff08;默认值为5&#xff09;超过阈值时产生该告警。 用户可通过“系统设置 > 阈值配置…

OpenCV的应用——道路边缘检测

OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉库&#xff0c;它提供了丰富的图像处理和计算机视觉算法&#xff0c;使得开发者可以便捷地进行图像处理、对象识别、图像分割等任务。道路边缘检测是计算机视觉中的重要应用之一&…

帝国CMS仿核弹头H5小游戏模板/帝国CMS内核仿游戏网整站源码

帝国CMS仿核弹头H5小游戏模板&#xff0c;帝国CMS内核仿游戏网整站源码。比较适合小游戏发布、APP应用资讯类网站使用&#xff0c;有兴趣的可以二次开发试试。 下载地址&#xff1a;https://bbs.csdn.net/topics/617579435

uniapp基础学习笔记01

文章目录 本博客根据黑马教程学习uniapp一、技术架构二、创建项目2.1 Hbuilder创建2.2 插件安装2.3 微信开发者工具配置与运行2.3.1 简单修改基础页面 2.4 pages.json和tabBar2.4.1 pages.json与tabBar配置2.4.2 案例 三、uniapp与原生开发的区别 本博客根据黑马教程学习uniapp…

C# Socket通信从入门到精通(10)——如何检测两台电脑之间的网络是否通畅

前言: 我们在完成了socket通信程序开发以后,并且IP地址也设置好以后,可以先通过一些手段来测试两台电脑之间的网络是否通畅,如果确认了网络通畅以后,我们再测试我们编写的Socket程序。 1、同时按下键盘的windows键+"R"键,如下图: 下面两张图是两种键盘的情…

参考意义大。4+巨噬细胞相关生信思路,简单易复现。

今天给同学们分享一篇生信文章“Angiogenesis regulators S100A4, SPARC and SPP1 correlate with macrophage infiltration and are prognostic biomarkers in colon and rectal cancers”&#xff0c;这篇文章发表在Front Oncol期刊上&#xff0c;影响因子为4.7。 结果解读&a…

【探索Linux】—— 强大的命令行工具 P.15(进程间通信 —— system V共享内存)

阅读导航 引言一、system V的概念二、共享内存(1) 概念(2) 共享内存示意图(3) 共享内存数据结构 三、共享内存的使用1. 共享内存的使用步骤&#xff08;1&#xff09;包含头文件&#xff08;2&#xff09;获取键值&#xff08;ftok函数&#xff09;&#xff08;3&#xff09;创…

LeetCode - 142. 环形链表 II (C语言,快慢指针,配图)

如果你对快慢指针&#xff0c;环形链表有疑问&#xff0c;可以参考下面这篇文章&#xff0c;了解什么是环形链表后&#xff0c;再做这道题会非常简单&#xff0c;也更容易理解下面的图片公式等。 LeetCode - 141. 环形链表 &#xff08;C语言&#xff0c;快慢指针&#xff0c;…

写作脑科学——屠龙的高效写作指南

ISBN: 978-7-115-59231-6 作者&#xff1a;杨滢&#xff08;屠龙的胭脂井&#xff09; 页数&#xff1a;201页 阅读时间&#xff1a;2023-09-09 推荐指数&#xff1a;★★★★★ 十分推荐这本书&#xff0c;写的非常简单易懂&#xff0c;里面有很多方法论和实用技巧&#xff0c…

使用Maxent模型预测适生区

Maxent模型因其在潜在适生区预测中稳健的表现&#xff0c;时下已经成为使用最广泛的物种分布模型。biomod虽然可以通过集成模型的优势来弥补数据量较小的劣势&#xff0c;但是其在使用和运算时间上的优势远不如Maxent&#xff0c;虽然最新的biomod2已经修复了一些bug&#xff0…

Power Apps-使用power Automate流

创建&#xff1a;Power Automate-创建power Apps使用的流-CSDN博客 打开Power Apps&#xff0c;创建页面&#xff0c;添加三个输入框&#xff08;分别是换算前单位、换算后单位、货币数&#xff09;&#xff0c;和一个文本框&#xff08;输出结果&#xff09;以及一个按钮 在…

微信聚合聊天,自动回复

微信&#xff0c;这款融合通讯、社交、娱乐、小程序于一体的平台&#xff0c;已经深深融入我们的日常生活。作为我们日常生活中不可或缺的社交工具&#xff0c;尤其在工作中&#xff0c;我们需要通过微信来沟通客户&#xff0c;这个时候我们就会希望有快速回复客户的方式秒回客…

自动备份pgsql数据库

bat文件中的内容&#xff1a; PATH D:\Program Files\PostgreSQL\13\bin;D:\Program Files\7-Zip set PGPASSWORD**** pg_dump -h 8.134.151.187 -p 5466 -U sky -d mip_db --schema-only -f D:\DB\backup\%TODAY%-schema-mip_db_ali.sql pg_dump -h 8.134.151.187 -p 5466…

从房地产先后跨界通信、文旅演艺领域,万通发展未来路在何方?

近年来&#xff0c;房地产市场可谓负重前行&#xff0c;各大房企纷纷谋求新出路。 作为中国最早的房企之一&#xff0c;万通发展再次处在转型变革的十字路口。自去年以来&#xff0c;万通发展在转型升级之路上动作频频&#xff0c;可谓忙得不亦乐乎。 大幕落下之时&#xff0c;…