JAVA面试——创建线程有几种方法?

1.继承Thread类:创建一个类,继承自 Thread 类,并重写 run() 方法来定义线程的执行逻辑。然后可以实例化这个类并调用 start() 方法来启动线程。

public class MyThread extends Thread {@Overridepublic void run() {// 线程执行逻辑for (int i = 0; i < 5; i++) {System.out.println("当前线程: " + Thread.currentThread().getName() + ",i = " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}
}

在这个例子中,MyThread 类继承了 Thread 类,并重写了 run() 方法来定义线程的执行逻辑,这里简单地打印输出一些信息并暂停 1 秒。在 main 方法中,我们实例化了 MyThread 类并调用 start() 方法来启动线程。

继承 Thread 类的方式相对简单直接,但也存在一些局限性,因为 Java 不支持多重继承,所以继承了 Thread 类之后就无法再继承其他类。另外,如果想要共享实例变量,也不太方便。

总结起来,继承 Thread 类是一种简单直接的创建线程的方式,适合一些简单的线程逻辑,但在复杂的场景中可能需要考虑其他方式。

2.实现Runnable接口:创建一个类,实现 Runnable 接口,并实现 run() 方法来定义线程的执行逻辑。然后可以将这个类的实例传递给 Thread 类的构造函数来创建线程。

public class MyRunnable implements Runnable {@Overridepublic void run() {// 线程执行逻辑for (int i = 0; i < 5; i++) {System.out.println("当前线程: " + Thread.currentThread().getName() + ",i = " + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Main {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread thread = new Thread(myRunnable);thread.start();}
}

在这个例子中,MyRunnable 类实现了 Runnable 接口,并重写了 run() 方法来定义线程的执行逻辑,这里简单地打印输出一些信息并暂停 1 秒。在 main 方法中,我们创建了 MyRunnable 的实例,并将其传递给 Thread 的构造函数来创建线程。最后调用 thread.start() 来启动线程。

需要注意的是,run() 方法不会返回任何结果,没有返回值。如果需要获取线程的执行结果,可以使用 Callable 接口来代替。

总结起来,实现 Runnable 接口是一种比较常见的创建线程的方式,它不仅简单易用,而且可以方便地共享实例变量。

3.实现Callable接口:它可以让线程执行完后返回一个结果或者抛出一个异常。与 Runnable 接口不同的是,Callable 接口中的 call() 方法可以声明抛出异常,并且可以有返回值。

import java.util.concurrent.Callable;public class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 1; i <= 100; i++) {sum += i;}return sum;}
}public class Main {public static void main(String[] args) throws Exception {Callable<Integer> myCallable = new MyCallable();FutureTask<Integer> futureTask = new FutureTask<>(myCallable);Thread thread = new Thread(futureTask);thread.start();System.out.println("计算结果:" + futureTask.get());}
}

在这个例子中,MyCallable 类实现了 Callable 接口,并实现了 call() 方法来定义线程的执行逻辑,这里是计算 1-100 的和并返回。在 main 方法中,我们将 MyCallable 实例传递给 FutureTask 的构造函数,再将 FutureTask 实例传递给 Thread 的构造函数来创建线程并启动执行。最后调用 futureTask.get() 方法来获取线程的返回结果。

需要注意的是,call() 方法可以声明抛出异常,并且可以有返回值。同时,在本例中,我们使用了 FutureTask 来获取线程执行结果,它是一个包装器,可以将 Callable 转换成 Future。

总之,实现 Callable 接口可以让我们更方便地同时获取线程的返回结果和异常信息,提高了代码的可靠性和可读性。

4.使用线程池的方式创建线程:使用线程池可以更好地管理和复用线程资源,从而提高程序的性能和效率。Java 提供了 Executor 框架来创建和管理线程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Main {public static void main(String[] args) {// 创建线程池,指定线程数为 5ExecutorService executor = Executors.newFixedThreadPool(5);// 提交任务给线程池for (int i = 0; i < 10; i++) {Runnable worker = new WorkerThread("任务 " + (i + 1));executor.execute(worker);}// 关闭线程池executor.shutdown();}
}class WorkerThread implements Runnable {private String taskName;public WorkerThread(String taskName) {this.taskName = taskName;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " 开始执行任务:" + taskName);try {// 模拟任务执行时间Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 完成任务:" + taskName);}
}

在这个例子中,我们通过 Executors.newFixedThreadPool(5) 创建了一个固定大小为 5 的线程池。然后我们提交了 10 个任务给线程池,每个任务都是一个实现了 Runnable 接口的 WorkerThread 类。每个任务会被线程池中的一个线程执行。

最后,我们调用 executor.shutdown() 关闭线程池。这会等待所有已提交的任务执行完毕,并且不再接受新的任务。

使用线程池可以有效地管理线程的创建和销毁,避免了频繁创建和销毁线程的开销。此外,线程池还提供了一些额外的功能,例如线程调度、线程超时等,能更好地控制线程的执行。

总结起来,使用线程池能够更好地管理和复用线程资源,提高程序的性能和效率。

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

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

相关文章

Spring security之授权

前言 本篇为大家带来Spring security的授权&#xff0c;首先要理解一些概念&#xff0c;有关于&#xff1a;权限、角色、安全上下文、访问控制表达式、方法级安全性、访问决策管理器 一.授权的基本介绍 Spring Security 中的授权分为两种类型&#xff1a; 基于角色的授权&…

一篇文章带你搞定CTFMice基本操作

CTF比赛是在最短时间内拿到最多的flag&#xff0c;mice必须要有人做&#xff0c;或者一支战队必须留出一块时间专门写一些mice&#xff0c;web&#xff0c;pwn最后的一两道基本都会有难度&#xff0c;这时候就看mice的解题速度了&#xff01; 说实话&#xff0c;这是很大一块&…

MATLAB画球和圆柱

1. 画球 修改了一下MATLAB的得到球的坐标的函数&#xff1a; GetSpherePoint function [xx,yy,zz] GetSpherePoint(xCenter,yCenter,zCenter,r,N) % 在[xCenter,yCenter,zCenter]为球心画一个半径为r的球,N表示球有N*N个面&#xff0c;N越大球的面越密集 if nargin < 4 …

GO设计模式——19、中介者模式(行为型)

目录 中介者模式&#xff08;Mediator Pattern&#xff09; 中介者模式的核心角色&#xff1a; 优缺点 使用场景 注意事项 代码实现 中介者模式&#xff08;Mediator Pattern&#xff09; 中介者模式&#xff08;Mediator Pattern&#xff09;引入一个中介者对象&#xf…

【NR技术】 Inter-gNB-DU 条件切换或条件Pcell变更

1 引言 本文介绍Inter-gNB-DU 条件切换或条件Pcell更改过程。 2 Inter-gNB-DU 条件切换或条件pcell更改 此过程用于在NR操作期间&#xff0c;UE从一个gNB-DU移动到同一gNB-CU内的另一个gNB-DU&#xff0c;以进行有条件的切换或有条件的Pcell更改。图1显示了内部NR的gNB-DU间…

Android studio Android SDK下载安装

我们访问地址 https://developer.android.google.cn/studio?hlzh-cn 拉下来直接点击下载 然后来下来 勾选 然后点击下载 下载好之后 我们双击打开 点击下一步 确认上面的勾选 然后下一步 这里 我们选择一下安装目录 然后点击下一步 安装 安装完之后点击进行下一步 Fin…

导行电磁波从纵向场分量求其他方向分量的矩阵表示

导行电磁波从纵向场分量求解其他方向分量的矩阵表示 导行电磁波传播的特点 电磁波在均匀、线性、各向同性的空间中沿着 z z z轴传播&#xff0c;可用分离变量法将时间轴、 z z z轴与 x , y x,y x,y轴分离&#xff0c;电磁波的形式可表示为&#xff1a; E ⃗ E ⃗ ( x , y )…

ImageBind-LLM: Multi-modality Instruction Tuning 论文阅读笔记

ImageBind-LLM: Multi-modality Instruction Tuning 论文阅读笔记 Method 方法Bind NetworkRMSNorm的原理及与Layer Norm的对比 Related Word / Prior WorkLLaMA-Adapter 联系我们 本文主要基于LLaMA和ImageBind工作&#xff0c;结合多模态信息和文本指令来实现一系列任务。训练…

yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。‘yarn‘ 不是内部或外部命令,也不是可运行的程序.解决方案

文章目录 报错截图介绍方法一方法二评论截图 报错截图 介绍 我的npm已经安装好了, 是可以运行npm -v 来查看版本的 这个时候报 yarn 不是内部或外部命令 相信你的npm也已经安装好了 我下面两个方法都进行了, 具体起作用的我也不知道是哪个, 都试试吧, 我成功了 注意尝试后关…

论文阅读——BLIP-2

BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models 1 模型 在预训练视觉模型和预训练大语言模型中间架起了一座桥梁。两阶段训练&#xff0c;视觉文本表示和视觉到语言生成学习。 Q-Former由两个转换器子模块组成&am…

Mybatis-TypeHandler类型转换器

文章目录 TypeHandler 接口TypeHandler 注册TypeHandler 查询别名管理总结 TypeHandler 接口 TypeHandler 这个接口 就是Mybatis的类型转换器 /*** author Clinton Begin*/ public interface TypeHandler<T> {// 在通过PreparedStatement为SQL语句绑定参数时&#xff0…

【12.22】转行小白历险记-算法01

不会算法的小白不是好小白&#xff0c;可恶还有什么可以难倒我这个美女的&#xff0c;不做花瓶第一天&#xff01; 一、长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 1.思路 滑动窗口法&#xff1a;把数组的区间&#xff0c;假设成为两…

stm32项目(14)——基于stm32f103zet6的循迹避障小车

1.功能设计 stm32循迹避障小车&#xff0c;使用超声波测距&#xff0c;使用红外循迹模块追踪黑线&#xff0c;实现循迹功能。此外&#xff0c;还可以检测烟雾、火焰、人体、温湿度。温湿度显示在LCD屏幕上。检测到有人、有火焰、有烟雾时&#xff0c;蜂鸣器报警&#xff01; 功…

强化学习(五)-Deterministic Policy Gradient (DPG) 算法及公式推导

针对连续动作空间&#xff0c;策略函数没法预测出每个动作选择的概率。因此使用确定性策略梯度方法。 0 概览 1 actor输出确定动作2 模型目标&#xff1a; actor目标&#xff1a;使critic值最大 critic目标&#xff1a; 使TD error最大3 改进&#xff1a; 使用两个target 网络…

Ceph存储体系架构?

Ceph体系架构主要由RADOS和RADOS GW和RBD以及CephFS构成。 RADOS&#xff08;Reliable, Autonomic Distributed Object Store&#xff09;是Ceph的底层核心&#xff0c;RADOS本身也是分布式存储系统&#xff0c;CEPH所有的存储功能都是基于RADOS实现。RADOS由两个组件组成&…

【接口测试】JMeter调用JS文件实现RSA加密

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Vue.js实战:构建现代单页应用程序(SPA)的实用指南

欢迎来到《Vue.js实战指南》&#xff01;本博客将深入探讨如何通过Vue.js构建现代单页应用程序&#xff08;SPA&#xff09;。无论你是初学者还是有一定经验的开发者&#xff0c;这里都有关键的实用指南&#xff0c;帮助你从概念到实际应用中构建强大的SPA。准备好迎接Vue.js的…

SQL分类

SQL分类 DDL 查询库 查询表 创建表 修改表 DML 添加数据 修改数据 删除数据 DQL 基本查询 条件查询 聚合函数 分组查询 排序查询 分页查询 执行顺序 DCL 管理用户 管理权限 数据类型 数值类型 字符串类型 日期类型

【Py/Java/C++三种语言OD2023C卷真题】20天拿下华为OD笔试之【模拟】2023C-结队编程【欧弟算法】全网注释最详细分类最全的华为OD真题题解

文章目录 题目描述与示例题目描述输入描述输出描述示例一输入输出说明 示例二输入输出说明 解题思路代码PythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目描述与示例 题目描述 某部门计划通过结队编程来进行项目开发&#xff0c;已知该部门有 N 名员工…

startUML6.0.1破解方法

startUML6.0.1破解方法 文章目录 startUML6.0.1破解方法1.startUML6.0.1快速破解2.概述3.安装Nodejs4.安装asar5.修改app.asar中的源码6.将修改后的源码重新压缩7.覆盖官方的asar文件8.重启startUML9.参考文档 1.startUML6.0.1快速破解 后绪步骤可以不看&#xff0c;直接下载我…