Java并发编程基础_Thread类

线程 Thread.class

image.png

1. 线程的六种状态

image.png

  • NEW
    尚未启动的线程处于此状态。
  • RUNNABLE
    在Java虚拟机中执行的线程处于此状态。
  • BLOCKED
    被阻塞等待监视器锁定的线程处于此状态。
  • WAITING
    正在等待另一个线程执行特定动作的线程处于此状态。
  • TIMED_WAITING
    正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
  • TERMINATED
    已退出的线程处于此状态。
Thread.State getState()	// 返回此线程的状态。  

image.png

2. 线程的常用方法

long getId()					// 返回此线程的标识符。
static Thread currentThread()	// 返回对当前正在执行的线程对象的引用。String getName()	// 返回此线程的名称。
void setName(String name)	// 将此线程的名称更改为等于参数 name 。void setPriority(int newPriority)	// 更改此线程的优先级。
int getPriority()	// 返回此线程的优先级。boolean	isAlive()			// 测试这个线程是否活着。
boolean	isInterrupted()	    // 测试当前线程是否中断。void start()	 // 导致此线程开始执行; Java虚拟机调用此线程的run方法。
void interrupt() // 中断这个线程。void join()	 // 等待这个线程死亡(用来控制线程结束的顺序,让调用这个方法的线程先执行完)
// 调用该方法的线程将会一直占用处理机,把其它线程都阻塞,直至该线程结束,再执行其它线程
// 同样使用join()也会产生异常InterruptExceptionstatic void	sleep(long millis) // 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)
// sleep执行后会产生异常InterruptedException,需要捕捉或抛出
// 每个对象都有一把锁,sleep不会释放这把锁static void	yield()	// 对调度程序的一个暗示,即当前线程愿意产生当前使用的处理器。
// 礼让线程,让当前正在执行的线程暂停,从运行状态转换为就绪状态
// 礼让不一定成功,可能CPU依旧重新调度该线程
public Thread()					// 分配一个新的Thread对象。
public Thread(String name)		// 创建一个新的Thread对象,并指定线程名称
public Thread(Runnable target)	// 封装Runnable对象为线程对象
public Thread(Runnable target, String name)	// 封装Runnable对象为线程对象,并指定线程名称

3. 线程的创建

3.1. 继承Thread类

继承Thread类,重写run()方法,调用start()启动线程

public class TestThread extends Thread {@Overridepublic void run() {// 线程运行逻辑}
}public class Main {public static void main(String [] args) {TestThread testThread = new TetsThread();testThread.strat();}
}

3.2. 实现Runnable接口

继承Thread类,重写run()方法,调用start()启动线程

public class TestThread implements Runnabel {@Overridepublic void run() {// 线程运行逻辑}
}public class Main {public static void main(String [] args) {TestThread testThread = new TetsThread();// Thread thread = new Thread(testThread);// thread.start();// 更简便的写法new Thread(testThread).start();}
}
  • 继续Thread类虽然启动线程的方式更简单,但是具有单继承局限性;
  • 实现Runnable接口,启动线程需要使用new一个Thread类来启动,但是可以避免单继承局限性(用于实现一份资源,多个代理)
public class TestThread implements Runnable {// 票数private int ticketNums = 10;// 模拟抢票@Overridepublic void run() {while (true) {if (ticketNums <= 0) {break;}System.out.println(Thread.currentThread().getName() + "-->拿到了第" + ticketNums-- +"票" )}}public static void main(String[] args) {TsetThread ticket = new TestThread();// 虽然有多个对象,但是都共用一份资源new Thread(ticket, "a").start();new Thread(ticket, "b").start();new Thread(ticket, "c").start();}
}

3.3. 实现Callable接口

实现Callable接口,定义接口返回值类型,重写call方法并抛出异常
相比Runnable接口,Callable接口允许线程执行任务并返回结果,它的call()方法还可以自定义抛出异常。

public class TestCallable implements Callable<Boolean> {// 定义成员变量// 定义构造器@Overridepublic Boolean call() throws Exception {// 编写线程需要执行的任务return true;}public static void main(String[] args) throws Exception {// 创建线程池ExecutorService ser = Executors.newFixedThreadPool(1);// 提交Callable任务,并获取Future对象Future<Boolean> future = executor.submit(new TestCallable());// 获取线程执行结果Boolean result = future.get();System.out.println(result);// 关闭线程池executor.shutdown();}
}

Callable创建线程的底层原理

  1. 当通过**ExecutorService****submit()**方法提交**Callable**任务时,线程池会将**Callable**任务封装成一个**FutureTask**对象。
  2. **FutureTask**对象实现了**RunnableFuture**接口,而**RunnableFuture**接口继承自**Runnable**接口,因此**FutureTask**对象也可以作为**Runnable**任务被线程执行。
  3. 线程池会选择一个空闲的线程执行**FutureTask**对象中的**run()**方法,而**run()**方法实际上会调用**Callable**对象的**call()**方法执行任务。
  4. 当任务执行完成后,**FutureTask**对象会保存任务的执行结果,其他线程可以通过**Future**对象的**get()**方法获取执行结果。

注意:

  1. 多线程中,主线程调用完start()之后,会继续执行自己路线,并不用等子线程执行完了再继续执行下去;

image.png

  1. 线程启动之后,并不一定立即执行,只是进入了线程就绪状态,具体运行时间由CPU调度安排(也就是说在多线程环境下,即使多个线程依次start但真实执行顺序却不一定按序);

补充:
函数式接口:

  1. 接口中只包含唯一一个抽象方法,就称为函数式接口,例如Runnable接口就是一个函数式接口;对于函数式接口可以直接用lambda表达式直接创建该接口的对象;
  2. 编写函数式强制接口里面只能有一个抽象方法,使用时需带有这个注释@FunctionalInterface,该注解可用于一个接口的定义上。一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错.
@FunctionalInterface
public interface Runnable {/*** When an object implementing interface <code>Runnable</code> is used* to create a thread, starting the thread causes the object's* <code>run</code> method to be called in that separately executing* thread.* <p>* The general contract of the method <code>run</code> is that it may* take any action whatsoever.** @see     java.lang.Thread#run()*/public abstract void run();
}
package text1;public class TestLambda {// 3. 静态内部类static class Like2 implements ILike {@Overridepublic void lambda() {System.out.println("静态内部类接口实例化");}}public static void main(String[] args) {ILike like = new Like();like.lambda();like = new Like2();like.lambda();// 4. 局部内部类class Like3 implements ILike {@Overridepublic void lambda() {System.out.println("局部内部类接口实例化");}}like = new Like3();like.lambda();// 5. 匿名内部类like = new ILike() {@Overridepublic void lambda() {System.out.println("匿名内部类接口实例化");}};like.lambda();// 6. lambda表达式简化匿名内部类like = () -> {System.out.println("匿名内部类接口实例化");};like.lambda();// 7. lambda表达式简化like = () -> System.out.println("lambda表达式简写");like.lambda();}}// 1. 定义一个函数式接口
interface ILike {void lambda();
}// 2. 实现类
class Like implements ILike {@Overridepublic void lambda() {System.out.println("1");}
}

Lambda表达式

  1. 用于简化函数式接口的实例对象,本质其实是一个接口的实例对象;
  2. 语法:

Lambda表达式的标准格式为:(参数类型 参数名称) ‐> { 代码语句 }

  1. 小括号里面放参数列表
  2. 箭头用来连接参数列表和方法体
  3. 箭头后面的大括号内放方法体
  4. 语法省略规则:
    1. 参数列表中的所有参数类型都可以省略,但需要同时省略;若只有一个参数,小括号都可以同时省略,如(String s)简写成s
    2. 如果方法体里只有一行代码,就可以直接省略大括号{}和语句结尾的分号;

如:hh( (String s)-> {System.out.println(s) } ),因为在hh这个方法的参数列表中提前指明了接口类型 , 所以写成Lambda形式,是能被系统自动识别出是对谁的简写。

4. 线程的关闭

线程关闭可以使用设置标志位flag的方法,设定当线程方法体中达成了某种变化使得标志位改变,从而使线程停止;
不推荐使用JDK已废弃的stop()方法和destroy()方法

@Override
public void run() {while (flag) {// 线程执行内容}
}

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

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

相关文章

C++中浅拷贝和深拷贝对象复制概念

1.浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a; 浅拷贝是指在对象复制时&#xff0c;只是复制对象的值&#xff0c;而不会复制对象指向的资源。这意味着对象和其副本会指向同一块内存空间&#xff0c;当一个对象改变时&#xff0c;另一个对象也会受到影响。 #inclu…

回溯算法|216.组合总和III

力扣题目链接 class Solution { private:vector<vector<int>> result; // 存放结果集vector<int> path; // 符合条件的结果// targetSum&#xff1a;目标和&#xff0c;也就是题目中的n。// k&#xff1a;题目中要求k个数的集合。// sum&#xff1a;已经收集…

OpenKylin安装Kafka

一、操作系统 openKylin 1.0.1 X86 二、下载安装包 # 安装依赖jdk sudo apt-get update sudo apt-get install default-jdk # 下载kafka mkdir -p /data/software/kafka wget https://archive.apache.org/dist/kafka/2.4.1/kafka_2.13-2.4.1.tgz三、解压安装 # 解压缩Kafka…

springboot项目学习-瑞吉外卖(4)续

1.任务 菜品的添加功能(涉及到两张表的数据添加) 2.菜品添加 功能页面如上&#xff0c;该页面有两个注意点 菜品分类&#xff1a;点击菜品分类后&#xff0c;会展示当前已有菜品&#xff1a;这个功能的实现要从category表里查询数据&#xff0c;然后再做展示口味做法配置&#…

算法题->移动零的C语言和JAVA的双指针解法

使用C语言和JAVA代码通过双指针进行解题 题目描述:给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 理解题意:不改变数组中非零元素的顺序,并把0元素放在非零元素后面. 链接: https://leetcode.cn/problems/m…

Linux——将云服务器作为跳板机,frp实现内网穿透

文章目录 操作步骤1. 准备工作&#xff1a;2. 配置frp服务器端&#xff1a;3. 配置frp客户端&#xff1a;4. 启动frp客户端&#xff1a;5. 测试连接&#xff1a;6. 安全注意事项&#xff1a; 云服务器性能分析阿里云具体操作步骤1. 购买&#xff1a;2. 登录&#xff1a;3. 首次…

springboot企业级抽奖项目业务四 (缓存预热)

缓存预热 为什么要做预热: 当活动真正开始时&#xff0c;需要超高的并发访问活动相关信息 必须把必要的数据提前加载进redis 预热的策略: 在msg中写一个定时任务 每分钟扫描一遍card_game表 把(开始时间 > 当前时间)&& (开始时间 < 当前时间1分钟)的活动及相…

CrossOver软件2024免费 最新版本详细介绍 CrossOver软件好用吗 Mac电脑玩Windows游戏

CrossOver是一款由CodeWeavers公司开发的软件&#xff0c;它可以在Mac和Linux等操作系统上运行Windows软件&#xff0c;而无需在计算机上安装Windows操作系统。这款软件的核心技术是Wine&#xff0c;它是一种在Linux和macOS等操作系统上运行Windows应用程序的开源软件。 Cross…

大语言模型---强化学习

本文章参考&#xff0c;原文链接&#xff1a;https://blog.csdn.net/qq_35812205/article/details/133563158 SFT使用交叉熵损失函数&#xff0c;目标是调整参数使模型输出与标准答案一致&#xff0c;不能从整体把控output质量 RLHF&#xff08;分为奖励模型训练、近端策略优化…

HarmonyOS 应用开发之FA模型绑定Stage模型ServiceExtensionAbility

本文介绍FA模型的三种应用组件如何绑定Stage模型的ServiceExtensionAbility组件。 PageAbility关联访问ServiceExtensionAbility PageAbility关联访问ServiceExtensionAbility和PageAbility关联访问ServiceAbility的方式完全相同。 import featureAbility from ohos.ability…

Adaboost集成学习 | Matlab实现基于ELM-Adaboost极限学习机结合Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 基于ELM-Adaboost极限学习机结合Adaboost集成学习时间序列预测(股票价格预测) 单变量时间序列单步预测。 ELM(Extreme Learning Machine,极限学习机)和AdaBoost(Adaptive Boosting,自适应提升)都是机…

c++----list模拟实现

目录 1. list的基本介绍 2. list的基本使用 2.1 list的构造 用法示例 2.2 list迭代器 用法示例 2.3. list容量&#xff08;capacity&#xff09;与访问&#xff08;access) 用法示例 2.4 list modifiers 用法示例 2.5 list的迭代器失效 3.list的模拟实现 3.1…

使用Python实现ID3决策树中特征选择的先后顺序,字节跳动面试真题

def empty1(pri_data): hair [] #[‘长’, ‘短’, ‘短’, ‘长’, ‘短’, ‘短’, ‘长’, ‘长’] voice [] #[‘粗’, ‘粗’, ‘粗’, ‘细’, ‘细’, ‘粗’, ‘粗’, ‘粗’] sex [] #[‘男’, ‘男’, ‘男’, ‘女’, ‘女’, ‘女’, ‘女’, ‘女’] for o…

leetcode.209.长度最小的子数组

题目 给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组&#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0。 示例&#xff1a; 输入&#xff1a;s 7, nums [2,3,1,2,4,3] 输出&#…

sqli第24关二次注入

注入点 # Validating the user input........$username $_SESSION["username"];$curr_pass mysql_real_escape_string($_POST[current_password]);$pass mysql_real_escape_string($_POST[password]);$re_pass mysql_real_escape_string($_POST[re_password]);if($p…

wps斜线表头并分别打字教程

wps斜线表头怎么做并分别打字&#xff1a; 1、首先选中我们想要设置的表头。 2、接着右键选中它&#xff0c;点击“设置单元格格式” 3、然后点击上方“边框”选项卡。 4、随后选择图示的斜线&#xff0c;点击“确定” 5、设置完成后&#xff0c;我们只要在其中打字就可以在斜…

算法学习——LeetCode力扣图论篇2

算法学习——LeetCode力扣图论篇2 1020. 飞地的数量 1020. 飞地的数量 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个大小为 m x n 的二进制矩阵 grid &#xff0c;其中 0 表示一个海洋单元格、1 表示一个陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相…

优化选址问题 | 基于帝国企鹅算法求解工厂-中心-需求点三级选址问题含Matlab源码

目录 问题代码问题 "帝国企鹅算法"并不是一个广为人知的优化算法,可能是一个特定领域或者特定情境下提出的方法。不过,对于工厂-中心-需求点三级选址问题,它可能是一种启发式优化方法,用于在多个候选位置中选择最优的工厂、中心和需求点位置。 这类问题通常涉及…

HTML基本元素

文章目录 如何制作标题如何制作文字如何做粗体字检查我们程序码给输出文字添加属性 HTML 一个HTML标签包含着&#xff1a; 起始标签&#xff1a;它包含了元素的名字&#xff0c;夹在一对 <、>&#xff08;尖括号&#xff09;之间。它指明元素从何处开始生效。结束标签&am…

java数组与集合框架(二)-- 集合框架,Iterator迭代器,list

集合框架&#xff1a; 用于存储数据的容器。 Java 集合框架概述 一方面&#xff0c;面向对象语言对事物的体现都是以对象的形式&#xff0c;为了方便对多个对象的操作&#xff0c;就要对对象进行存储。另一方面&#xff0c;使用Array存储对象方面具有一些弊端&#xff0c;而…