Java实现多线程有几种方式(满分回答)

news/2024/4/27 1:25:45/文章来源:https://blog.csdn.net/qq_37132495/article/details/129159883

目录

    • JDK8 创建的线程的两种方式
      • orcle文档解释
      • 方式一:继承Thread类
      • 方式二:实现Runnable接口
      • 同时用两种的情况
    • 其他间接创建方式
      • Callable接口
      • 线程池

JDK8 创建的线程的两种方式

orcle文档解释

orcle文档:https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html

image-20230222102145410

总结:

准确的讲,创建线程只有一种方式那就是构造Thread类,而实现线程的执行单元有两种方式:

  • 方法一:实现Runnable接口的重写run方法,并把Runnable实例传给Thread类
  • 方法二∶重写Threadrun方法(继承Thread类)

(其他一些方式,究其根本都是间接的通过上面两种方式创建的)

方式一:继承Thread类

public static void main(String[] args) {System.out.println("主线程运行:" + Thread.currentThread().getName());Task1 task = new Task1();task.start();}static class Task1 extends Thread{@Overridepublic void run() {for (int i = 0; i < 20; i++) {System.out.println("task1线程运行" + Thread.currentThread().getName());System.out.println("Task11继承Thread实现多线程");}}}}
  • 自定义线程类继承Thread类

  • 重写run()方法,编写线程执行体

  • 创建线程对象,调用start()方法启动线程

方式二:实现Runnable接口

public static void main(String[] args) {Task task = new Task();Thread thread  = new Thread(task);thread.start();}static class Task implements Runnable{@Overridepublic void run() {for (int i = 0; i < 20; i++) {System.out.println("task1线程运行" + Thread.currentThread().getName());System.out.println("Task11实现Runnable接口实现多线程");}}}
  • 定义MyRunnable类实现Runnable接口

  • 实现run()方法,编写线程执行体

  • 创建线程对象,调用start()方法启动线程

同时用两种的情况

public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("实现Runnable的run方法");}}){@Overridepublic void run() {System.out.println("匿名内部类,重写Thread类的run方法");}}.run();
}

结果:

匿名内部类,重写Thread类的run方法

分析:

这里使用的匿名内部类,在匿名内部类里面又重写了Thread类的run方法。创建Thread类的同时传入了Runnable对象,这时候Thread类的run已被重写,不再是原生方法的逻辑:执行传入task的run

image-20230211121531177

所以即便传入Runnable,也不会被执行。

其他间接创建方式

Callable接口

public static void main(String[] args) {Task task = new Task();FutureTask<Integer> ft = new FutureTask<>(task);Thread thread = new Thread(ft);thread.start();}static class Task implements Callable<Integer> {@Overridepublic Integer call() throws Exception {for (int i = 0; i < 20; i++) {System.out.println("task1线程运行" + Thread.currentThread().getName());System.out.println("Task11实现Callable接口实现多线程");}return 1;}
}

FutureTask实现了RunnableFuture接口,RunnableFuture继承了RunnableFuture接口。所以也是间接通过Runnable来创建的。

  • 实现Callable接口,需要返回值类型
  • 重写call方法,需要抛出异常
  • 创建目标对象
  • 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
  • 提交执行:Future result1 = ser.submit(t1);
  • 获取结果: boolean r1 = result1.get()
  • 关闭服务: ser.shutdownNow();

实现Runnable接口和Callable接口的区别

  • Runnable 接口不会返回结果,Callable 接口可以返回结果
  • Callable接口实现类中的run方法允许异常向上抛出,可以在内部处理,try catch,但是runnable接口实现类中run方法的异常必须在内部处理,不能抛出

线程池

ThreadPoolExecutor类的execute方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AEKGtqyC-1677038180765)(Java%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%B1%87%E6%80%BB%E6%80%BB%E7%BB%93%E7%AC%94%E8%AE%B0.assets/image-20230222115102680.png)]

public void execute(Runnable command) {if (command == null)throw new NullPointerException();/** Proceed in 3 steps:** 1. If fewer than corePoolSize threads are running, try to* start a new thread with the given command as its first* task.  The call to addWorker atomically checks runState and* workerCount, and so prevents false alarms that would add* threads when it shouldn't, by returning false.** 2. If a task can be successfully queued, then we still need* to double-check whether we should have added a thread* (because existing ones died since last checking) or that* the pool shut down since entry into this method. So we* recheck state and if necessary roll back the enqueuing if* stopped, or start a new thread if there are none.** 3. If we cannot queue task, then we try to add a new* thread.  If it fails, we know we are shut down or saturated* and so reject the task.*/int c = ctl.get();//如果工作线程数小于核心线程数,if (workerCountOf(c) < corePoolSize) {//执行addWorker,会创建一个核心线程,如果创建失败,重新获取ctlif (addWorker(command, true))return;c = ctl.get();}//如果工作线程数大于等于核心线程数,线程池的状态是RUNNING,并且可以添加进队列//(RUNNING状态下)如果添加失败,说明是队列已经满了,接着就去创建新的线程,如果大于最大线程数,则执行拒绝策略//如果线程池不是RUNNING状态,则执行拒绝策略(当然还会调addWorker进行判断一次)if (isRunning(c) && workQueue.offer(command)) {//再次获取ctl,进行双重检索(也就是对线程池的状态再次检查一遍)int recheck = ctl.get();//如果线程池是不是处于RUNNING的状态,那么就会将任务从队列中移除,//如果移除失败,则会判断工作线程是否为0 ,如果过为0 就创建一个非核心线程//如果移除成功,就执行拒绝策略,因为线程池已经不可用了;if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}else if (!addWorker(command, false))//线程池挂了或者大于最大线程数reject(command);
}

addWork方法会创建线程池内工作线程WorkerWorker这个线程,实现了Runnable接口,并持有一个线程thread,一个初始化的任务firstTask。thread是调用构造方法时通过ThreadFactory来创建的线程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TG3ITFgx-1677038180766)(Java%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%B1%87%E6%80%BB%E6%80%BB%E7%BB%93%E7%AC%94%E8%AE%B0.assets/image-20230222113722589.png)]

ThreadFactory中也是Runnable创建线程的模式。

在这里插入图片描述

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

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

相关文章

九龙证券|银行资本管理办法迎“大修” 信用风险权重法调整优化

1年期AAA中债商业银行同业存单到期收益率 日前迎来“大修”的商业银行本钱办理方法&#xff0c;在债券商场激起“涟漪”——债券商场一改此前平静态势&#xff0c;连续两日跌落。 2月21日&#xff0c;10年期国债收益率较上星期五上行2.9个基点&#xff0c;至2.919%&#xff1b…

Redis学习【10】之Redis主从集群(1)

文章目录一 Redis主从集群搭建1 伪集群搭建与配置1.1.1 分级管理1.1.2 容灾冷处理1.2 主从复制原理1.2.1 主从复制过程1.2.2 数据同步演变过程1.3 哨兵机制实现1.3.1 哨兵机制简介1.3.2 Redis 高可用集群搭建1.3.3 Redis 高可用集群的启动1.3.4 Sentinel 优化配置1.4 哨兵机制原…

Spring中自定义Session管理,Spring Session源码解析

系列文章&#xff1a;Spring Boot学习大纲&#xff0c;可以留言自己想了解的技术点 目录 系列文章&#xff1a;Spring Boot学习大纲&#xff0c;可以留言自己想了解的技术点 1、session是什么&#xff1f; 1>session在哪里&#xff1f; 2>服务器怎么知道每次说话的是…

H5盲盒抽奖系统源码

盲盒抽奖系统4.0&#xff0c;带推广二维码防洪炮灰功能和教程。 支持微信无限回调登录 标价就是源码价格&#xff0c;vuetp5框架编写&#xff0c;H5网页&#xff0c;前后端分离 此源码为正规开发&#xff0c;正版产品已申请软著。 开源无加密无授权&#xff0c;可以二开使用…

霍尔元件的应用

霍尔传感器有3个pin&#xff0c;分别是 正极 负极和输出pin。 输出pin接电阻和发光二极管。电阻起限流作用。 电源接5.5v直流电。当拿一个磁铁的N极靠近霍尔元件时&#xff0c;二极管越来越亮。当拿S极靠近霍尔元件时&#xff0c;二极管越来越暗。 N极磁场强度定义为正的磁场强…

算法刷题日志——移除元素,双指针

文章目录删除有序数组中的重复项[删除有序数组中的重复项 II](https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/)移除元素[283. 移动零](https://leetcode.cn/problems/move-zeroes/description/)[844. 比较含退格的字符串](https://leetcode.cn/problem…

Docker之路(3.docker底层原理、和虚拟机VM对比区别)

1.docker run 流程图 2. docker 底层原理 2.1 docker 是怎么工作的&#xff1f; Docker 是一个 Client-Server 结构的系统&#xff0c;Docker的守护进程运行在主机上&#xff0c; 通过Socket从客户端访问&#xff01; DockerServer接收到Docker-Client的指令&#xff0c;就会执…

【Java】Spring的创建和使用

Spring的创建和使用 Spring就是一个包含众多工具方法的IOC容器。既然是容器&#xff0c;那么就具备两个最主要的功能&#xff1a; 将对象存储到容器中从容器中将对象取出来 在Java语言当中对象也叫作Bean。 1. 创建Spring项目 创建一个普通maven项目添加Spring框架支持(spri…

Spring Boot自动装配的原理

Spring Boot自动装配的原理自动装配的实现EnableAutoConfigurationAutoConfigurationImportSelectorSpring Boot中的自动装配&#xff0c;它是Starter的基础&#xff0c;也是Spring Boot的核心。那么什么叫自动装配呢&#xff1f;或者说什么叫装配呢&#xff1f; 简单来说&…

金三银四丨黑蛋老师带你剖析-安全开发岗

作者丨黑蛋在之前呢&#xff0c;我们聊了二进制这块的病毒岗位&#xff0c;漏洞岗位&#xff0c;逆向岗位以及CTF这块的岗位。今天我们就来聊一聊安全开发类的工作岗位。首先网络安全方向中安全开发岗位都有哪些&#xff0c;安全开发主要指安全研发工程师或安全开发工程师&…

电子技术——负反馈特性

电子技术——负反馈特性 本节我们进一步深入介绍负反馈特性。 增益脱敏性 假设 β\betaβ 是一个常数。考虑下面的微分方程&#xff1a; dAfdA(1Aβ)2dA_f \frac{dA}{(1 A\beta)^2} dAf​(1Aβ)2dA​ 将上式除以 AfA1AβA_f \frac{A}{1A\beta}Af​1AβA​ 得到&#xff1…

php+vue加油站会员服务系统 java微信小程序

目 录 1绪论 1 1.1项目研究的背景 1 1.2开发意义 1 1.3项目研究现状及内容 5 1.4论文结构 5 2开发技术介绍 7 2.5微信小程序技术 8 3系统分析 9 3.1可行性分析 9 3.1.1技术可行性 9 3.1.2经济可行性 9 3.1.3操作可行性 10 3.2网站性能需求分析 10 3.3网站功能分析 10 3.4系统…

秒懂算法 | 子集树模型——0-1背包问题的回溯算法及动态规划改进

给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为W。一种物品要么全部装入背包,要么全部不装入背包,不允许部分装入。装入背包的物品的总重量不超过背包的容量。问应如何选择装入背包的物品,使得装入背包中的物品总价值最大? 01、问题分析——解空间及搜索…

JAVA并发集合之ConcurrentHashMap

ConcurrentHashMap是一个支持高并发更新与查询的哈希表(基于HashMap)。Hashmap在多线程并发的情况下&#xff0c;是线程不安全的&#xff0c;容易出现死循环、死锁等问题&#xff0c;JDK8后不会出现死锁问题&#xff0c;但依然存在多线程的系列问题&#xff0c;如&#xff1a;数…

关于虚拟数字人你想知道的都在这里

2022年底&#xff0c;微软旗下的人工智能实验室Open AI发布的对话式大型语言模型ChatGPT聊天机器人一夜蹿红&#xff0c;5天用户量超百万&#xff0c;在各大中外媒体平台掀起了一阵热潮。也带火了人工智能相关产业&#xff0c;AI虚拟数字人就是其中之一&#xff0c;一个随着元宇…

【电商】红冲与单价调整

产品及系统的规划与设计过程中始终会考虑实际生产环境中的异常场景&#xff0c;这样会增加系统复杂度&#xff0c;虽然有时可以通过简化流程来降低出现异常的概率&#xff0c;但很多时候都是无法避开的&#xff1b;本篇就简单梳理下红冲单与价格调整单方面的内容&#xff0c;希…

Java ”框架 = 注解 + 反射 + 设计模式“ 之 注解详解

Java ”框架 注解 反射 设计模式“ 之 注解详解 每博一文案 刹那间我真想令时光停住&#xff0c;好让我回顾自己&#xff0c;回顾失去的年华&#xff0c;缅怀哪个穿一身短小的连衣裙 和瘦窄的短衫的小女孩。让我追悔少年时代&#xff0c;我心灵的愚钝无知&#xff0c;它轻易…

解决 NestHost requires ASM7 (shrink、kotlin metadata)

① 场景 Caused by: java.lang.RuntimeException: NestHost requires ASM7Failed to resolve class org/vigame/demo/CrashHandler$1.class[transform input:not foundproject input:not foundaar input:not found]Caused by: java.lang.UnsupportedOperationException: NestH…

损失函数与反向传播

一、损失函数计算实际输出和目标之间的差距为我们更新输出提供一定的依据&#xff08;反向传播&#xff09;1.nn.L1Lossimport torch from torch.nn import L1Loss inputs torch.tensor([1,2,3],dtypetorch.float) targets torch.tensor([1,2,5],dtypetorch.float) # reshape…

ZED相机快速使用指南

1、安装SDK ZED SDK 3.8 - Download | Stereolabs 2、安装ros GitHub - stereolabs/zed-ros-wrapper: ROS wrapper for the ZED SDK 其他教程&#xff1a;ZED2相机SDK安装使用及ROS下使用_可即的博客-CSDN博客 3、官方文档 Get Started with ZED | Stereolabs 4、标定参…