【JavaSE】Java基础语法(三十四):实现多线程

news2024/11/26 22:48:54

文章目录

  • 1. 简单了解多线程
  • 2. 并发和并行
  • 3. 进程和线程
  • 4. 实现多线程方式一:继承Thread类【应用】
  • 5. 实现多线程方式二:实现Runnable接口【应用】
  • 6. 实现多线程方式三: 实现Callable接口【应用】
  • 7. 设置和获取线程名称【应用】
  • 8. 线程休眠【应用】
  • 9. 线程优先级【应用】
  • 10. 守护线程【应用】


在这里插入图片描述

1. 简单了解多线程


是指从软件或者硬件上实现多个线程并发执行的技术。
具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。


2. 并发和并行

  • 并行:在同一时刻,有多个指令在多个CPU上同时执行。
  • 并发:在同一时刻,有多个指令在单个CPU上交替执行。

3. 进程和线程

  • 进程:是正在运行的程序
    • 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位
    • 动态性:进程的实质是程序的一次执行过程,进程是动态产生,动态消亡的
    • 并发性:任何进程都可以同其他进程一起并发执行
  • 线程:是进程中的单个顺序控制流,是一条执行路径
    • 单线程:一个进程如果只有一条执行路径,则称为单线程程序
    • 多线程:一个进程如果有多条执行路径,则称为多线程程序

4. 实现多线程方式一:继承Thread类【应用】

  • 方法介绍
    在这里插入图片描述

  • 实现步骤
    • 定义一个类MyThread继承Thread类
    • 在MyThread类中重写run()方法
    • 创建MyThread类的对象
    • 启动线程

  • 代码演示
    public class MyThread extends Thread {
    	@Override
    	public void run() {
    		for(int i=0; i<100; i++) {
    			System.out.println(i);
    		}
    	}
    }
    
    public class MyThreadDemo {
    	public static void main(String[] args) {
    		MyThread my1 = new MyThread();
    		MyThread my2 = new MyThread();
    		// my1.run();
    		// my2.run();
    		//void start() 导致此线程开始执行; Java虚拟机调用此线程的run方法
    		my1.start();
    		my2.start();
    	}
    }
    

两个小问题

- 为什么要重写run()方法?
	- 因为run()是用来封装被线程执行的代码
- run()方法和start()方法的区别?
	- run():封装线程执行的代码,直接调用,相当于普通方法的调用
	- start():启动线程;然后由JVM调用此线程的run()方法

5. 实现多线程方式二:实现Runnable接口【应用】

  • Thread构造方法
    在这里插入图片描述

  • 实现步骤
    • 定义一个类MyRunnable实现Runnable接口
    • 在MyRunnable类中重写run()方法
    • 创建MyRunnable类的对象
    • 创建Thread类的对象,把MyRunnable对象作为构造方法的参数
    • 启动线程

  • 代码演示
    public class MyRunnable implements Runnable {
    	@Override
    	public void run() {
    		for(int i=0; i<100; i++) {
    			System.out.println(Thread.currentThread().getName()+":"+i);
    		}
    	}
    }
    
    public class MyRunnableDemo {
    	public static void main(String[] args) {
    		//创建MyRunnable类的对象
    		MyRunnable my = new MyRunnable();
    		//创建Thread类的对象,把MyRunnable对象作为构造方法的参数
    		//Thread(Runnable target)
    		// Thread t1 = new Thread(my);
    		// Thread t2 = new Thread(my);
    		//Thread(Runnable target, String name)
    		Thread t1 = new Thread(my,"坦克");
    		Thread t2 = new Thread(my,"飞机");
    		//启动线程
    		t1.start();
    		t2.start();
    	}
    }
    

6. 实现多线程方式三: 实现Callable接口【应用】

  • 方法介绍
    在这里插入图片描述

  • 实现步骤
    • 定义一个类MyCallable实现Callable接口
    • 在MyCallable类中重写call()方法
    • 创建MyCallable类的对象
    • 创建Future的实现类FutureTask对象,把MyCallable对象作为构造方法的参数
    • 创建Thread类的对象,把FutureTask对象作为构造方法的参数
    • 启动线程
    • 再调用get方法,就可以获取线程结束之后的结果。

  • 代码演示
    public class MyCallable implements Callable<String> {
    	@Override
    	public String call() throws Exception {
    		for (int i = 0; i < 100; i++) {
    			System.out.println("跟女孩表白" + i);
    		}
    		//返回值就表示线程运行完毕之后的结果
    		return "答应";
    	}
    }
    
    public class Demo {
    	public static void main(String[] args) throws ExecutionException,
    	InterruptedException {
    		//线程开启之后需要执行里面的call方法
    		MyCallable mc = new MyCallable();
    		//Thread t1 = new Thread(mc);
    		//可以获取线程执行完毕之后的结果.也可以作为参数传递给Thread对象
    		FutureTask<String> ft = new FutureTask<>(mc);
    		//创建线程对象
    		Thread t1 = new Thread(ft);
    		String s = ft.get();
    		//开启线程
    		t1.start();
    		//String s = ft.get();
    		System.out.println(s);
    	}
    }
    

三种实现方式的对比

  • 实现Runnable、Callable接口
    • 好处: 扩展性强,实现该接口的同时还可以继承其他的类
    • 缺点: 编程相对复杂,不能直接使用Thread类中的方法
  • 继承Thread类
    • 好处: 编程比较简单,可以直接使用Thread类中的方法
    • 缺点: 可以扩展性较差,不能再继承其他的类

7. 设置和获取线程名称【应用】

  • 方法介绍
    在这里插入图片描述
  • 代码演示
    public class MyThread extends Thread {
    	public MyThread() {}
    	
    	public MyThread(String name) {
    		super(name);
    	}
    	
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println(getName()+":"+i);
    		}
    	}
    }
    
    public class MyThreadDemo {
    	public static void main(String[] args) {
    	MyThread my1 = new MyThread();
    	MyThread my2 = new MyThread();
    	//void setName(String name):将此线程的名称更改为等于参数 name
    	my1.setName("高铁");
    	my2.setName("飞机");
    	//Thread(String name)
    	MyThread my1 = new MyThread("高铁");
    	MyThread my2 = new MyThread("飞机");
    	my1.start();
    	my2.start();
    	//static Thread currentThread() 返回对当前正在执行的线程对象的引用
    	System.out.println(Thread.currentThread().getName());
    	}
    }
    

8. 线程休眠【应用】

  • 相关方法
    在这里插入图片描述
  • 代码演示
    public class MyRunnable implements Runnable {
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			try {
    				Thread.sleep(100);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			System.out.println(Thread.currentThread().getName() + "---" + i);
    		}
    	}
    }
    
    public class Demo {
    	public static void main(String[] args) throws InterruptedException {
    		/*System.out.println("睡觉前");
    		Thread.sleep(3000);
    		System.out.println("睡醒了");*/
    		MyRunnable mr = new MyRunnable();
    		Thread t1 = new Thread(mr);
    		Thread t2 = new Thread(mr);
    		t1.start();
    		t2.start();
    	}
    }
    

9. 线程优先级【应用】

  • 线程调度

    • 两种调度方式
      • 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间
      • 抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随
        机选择一个,优先级高的线程获取的 CPU 时间片相对多一些
    • Java使用的是抢占式调度模型
    • 随机性
      假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的
  • 优先级相关方法
    在这里插入图片描述

  • 代码演示

    public class MyCallable implements Callable<String> {
    	@Override
    	public String call() throws Exception {
    		for (int i = 0; i < 100; i++) {
    			System.out.println(Thread.currentThread().getName() + "---" + i);
    		}
    		return "线程执行完毕了";
    	}
    }
    
    public class Demo {
    	public static void main(String[] args) {
    	//优先级: 1 - 10 默认值:5
    	MyCallable mc = new MyCallable();
    	FutureTask<String> ft = new FutureTask<>(mc);
    	Thread t1 = new Thread(ft);
    	t1.setName("飞机");
    	t1.setPriority(10);
    	//System.out.println(t1.getPriority());//5
    	t1.start();
    	MyCallable mc2 = new MyCallable();
    	FutureTask<String> ft2 = new FutureTask<>(mc2);
    	Thread t2 = new Thread(ft2);
    	t2.setName("坦克");
    	t2.setPriority(1);
    	//System.out.println(t2.getPriority());//5
    	t2.start();
    	}
    }
    

10. 守护线程【应用】

  • 相关方法

    //`将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出
    void setDaemon(boolean on)
    
  • 代码演示

    public class MyThread1 extends Thread {
    	@Override
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			System.out.println(getName() + "---" + i);
    		}
    	}
    }
    
    public class MyThread2 extends Thread {
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println(getName() + "---" + i);
    		}
    	}
    }
    
    public class Demo {
    	public static void main(String[] args) {
    		MyThread1 t1 = new MyThread1();
    		MyThread2 t2 = new MyThread2();
    		t1.setName("女神");
    		t2.setName("备胎");
    		//把第二个线程设置为守护线程
    		//当普通线程执行完之后,那么守护线程也没有继续运行下去的必要了.
    		t2.setDaemon(true);
    		t1.start();
    		t2.start();
    	}
    }
    

在这里插入图片描述

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

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

相关文章

[PyTorch][chapter 36][经典卷积神经网络-1 ]

前言&#xff1a; ILSVRC&#xff08;ImageNet Large Scale Visual Recognition Challenge&#xff09;是近年来机器视觉领域最受追捧也是最具权威的学术竞赛之一&#xff0c;代表了图像领域的最高水平。 ImageNet数据集是ILSVRC竞赛使用的是数据集&#xff0c;由斯坦福大学李…

多线程屏障CyclicBarrier

文章目录 前言一、CyclicBarrier可以做什么&#xff1f;二、使用步骤1 单参数CyclicBarrier2 多参数 CyclicBarrier3 与CyclicBarrier类似的Exchanger 总结 前言 多线程中的CyclicBarrier,同样也是juc包下的一个工具类; 一、CyclicBarrier可以做什么&#xff1f; CyclicBarri…

C#,码海拾贝(28)——求解“对称正定方程组”的“平方根法”之C#源代码,《C#数值计算算法编程》源代码升级改进版

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static partial class LEquations { /// <summary> /…

【译】Google Guava 的 Table 接口介绍

原文&#xff1a;https://www.baeldung.com/guava-table 1. 概述 在本教程中&#xff0c;我们将展示如何使用 Google Guava 的 Table 接口及其多个实现。 Guava 的 Table 是一种集合&#xff0c;表示包含行、列和相关单元格值的表结构&#xff0c;行和列充当有序的键对。 2…

React Native开发速记

文章目录 引子React Native适用场景React基础JSX 组件的定义基础APIFlex弹性布局例子: Flex布局实现多行多列 常用UI组件几个核心钩子函数useState用法useEffect典型用法 和原生模块交互调用原生模块方法 调试其它工具UI框架参考资源 引子 软件开发&#xff0c;移动优先&#…

webAJAX概述.

1.1什么是AJAX. Ajax即AsynchronousJavascript And XML&#xff1a;异步数据回调。 使用Ajax技术网页应用能够快速地将更新呈现在用户界面上&#xff0c;不需要重载&#xff08;刷新&#xff09;整个页面【只刷新局部】&#xff0c;这使得程序能够更快地回应用户的操作。、 1…

使用Node. js输出到命令行

目录 1、使用控制台模块的基本输出 2、清除控制台 3、计数元素 4、复位计数 5、打印堆栈跟踪 6、计算花费的时间 7、stdout和stderr 8、为输出着色 9、创建进度条 1、使用控制台模块的基本输出 Node.js提供了一个console模块&#xff0c;它提供了大量非常有用的与命令…

Qt Quick系列(4)—定位元素

&#x1f680;作者&#xff1a;CAccept &#x1f382;专栏&#xff1a;Qt Quick 文章目录 前言相对布局代码示例示例一示例二示例三示例四示例五示例六 简单"布局器"ColumnRowGridFlow 结语 前言 在Qt Quick中&#xff0c;可以使用以下方式来定位元素&#xff1a;…

需要建立强大的网络响应框架

由于头条新闻充斥着网络攻击&#xff0c;因此企业制定网络响应框架变得前所未有的重要。当今的网络安全形势继续快速发展&#xff0c;黑客行动主义、民族国家支持的网络攻击、勒索软件和其他攻击策略变得更加危险、复杂&#xff0c;组织的防御成本也越来越高。随着企业进行数字…

华为OD机试真题B卷 Java 实现【名字的漂亮度】,附详细解题思路

一、题目描述 给出一个字符串&#xff0c;该字符串仅由小写字母组成&#xff0c;定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。 每个字母都有一个“漂亮度”&#xff0c;范围在1到26之间。没有任何两个不同字母拥有相同的“漂亮度”。字母忽略大小写。 给出多个…

Ex-ChatGPT本地部署+Azure OpenAI接口配置+docker部署服务

Ex-ChatGPT项目分为 Ex-ChatGPT 和 WebChatGPTEnhance 两部分&#xff0c;Ex-ChatGPT启动后是个web服务&#xff0c;通过访问ip端口体验&#xff1b; WebChatGPTEnhance可编译生成一个浏览器插件&#xff0c;Chrome或者Microsoft edge浏览器可以安装该插件&#xff0c;点击该插…

Golang中文件目录操作的实现

目录 文件 文件目录 文件目录操作 读取文件 一、方法一 (file.Read()) 二、方法二 (bufio读取文件) 三、方法三 (ioutil 读取方法) 写入文件 一、方法一 二、方法二 三、方法三 (ioutil写入文件) 复制文件 一、方法一 二、方法二 文件 Golang中&#xff0c;文件是…

python异常处理速通

一.异常处理认识 1.基础认识 开发人员在编写程序时&#xff0c;难免会遇到错误&#xff0c;有的是编写人员疏忽造成的语法错误&#xff0c;有的是程序内部隐含逻辑问题造成的数据错误&#xff0c;还有的是程序运行时与系统的规则冲突造成的系统错误&#xff0c;等等。总的来说…

什么是肖特基二极管

普通二极管是由N型半导体和P型半导体接触制成&#xff0c;交界面形成PN结。 肖特基二极管是由N型半导体和金属接触制成&#xff0c;交界面形成肖特基结。 肖特基结的形成主要是因为N型半导体中的电子更容易逸出进入到金属&#xff0c;从而在接触面N型半导体失去电子形成正离子区…

python:绘制GAM非线性回归散点图和拟合曲线

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用python语言绘制广义线性模型&#xff08;Generalized Additive Model&#xff0c;GAM&#xff09;非线性回归散点图和拟合曲线。并记录了计算RMSE、ubRMSE、R2、Bias的代码。 文章目录 一、GAM非线性回归详解二、代码三、计算RM…

docker 镜像/容器的打包、导出、导入

目录 一、将变动过的容器打包生成新的镜像 二、对镜像进行导出导入 1、将镜像导出为一个镜像img文件 2、将img镜像文件导入&#xff0c;复制出一个完全一样镜像 三、对容器进行导入导出 1、将容器导出为一个镜像tar文件 2、将镜像tar文件导入&#xff0c;生成一个新镜像…

Linux本地搭建GitLab服务器 - 内网穿透远程访问

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar内网穿透5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 转载自cpolar极点云文章&#xff1a;Linux搭建GitLab私有仓库&#xff0c;并内网穿透实…

vite构建的项目如何修改element Plus的主题样式

安装element plus 安装icon pnpm install element-plus pnpm install element-plus/icons-vue main.ts配置 icon的使用https://element-plus.gitee.io/zh-CN/component/icon.html#%E7%BB%93%E5%90%88-el-icon-%E4%BD%BF%E7%94%A8 import { createApp } from vue import ./sty…

【工具】vscode的常用插件之git插件

&#x1f41a;作者简介&#xff1a;花神庙码农&#xff08;专注于Linux、WLAN、TCP/IP、Python等技术方向&#xff09;&#x1f433;博客主页&#xff1a;花神庙码农 &#xff0c;地址&#xff1a;https://blog.csdn.net/qxhgd&#x1f310;系列专栏&#xff1a;善假于物&#…

计算机视觉cv模型最新进展速看:

华为诺亚实验室等研究者提出动态分辨率网络 DRNet 深度卷积神经网络通畅采用精细的设计&#xff0c;有着大量的可学习参数&#xff0c;在视觉任务上实现很高精 确度要求。为了降低将网络部署在移动端成本较高的问题&#xff0c;近来发掘在预定义架构上的冗余 已经取得了巨大的…