【线程】Java多线程编程

【线程】Java多线程编程

      • 一、前言
        • 一个最简单的多线程编程示例
        • 可以使用的工具
      • 二、创建线程的方式
      • 三、Thread类中重要的属性和方法
        • 3.1 构造方法
        • 3.2 常见属性

一、前言

当有多个线程的时候,这些线程的执行顺序是不确定的。这一点,是我们之前提到的操作系统随即调度造成的。线程是系统调度的基本单位,进程是系统分配资源的基本单位。

什么叫做“随机调度”?

  1. 一个线程,什么时候被调度上CPU上执行,时机是不确定的;
  2. 一个线程,什么时候从CPU上下来,让其他线程上去,时机也是不确定的;
  3. 多个线程的执行顺序是不确定的。

所谓“随机调度”,我们可以将其理解为抢占式执行,即多个线程抢占CPU的使用权,但是谁抢到了,不确定。

一个最简单的多线程编程示例
public class ThreadDemo1 {public static void main(String[] args)  {MyThread t =new MyThread();t.start();while(true){System.out.println("hello world");}}
}class MyThread extends Thread{@Overridepublic void run() {while(true) {System.out.println("hello thread");}}
}

执行结果:
在这里插入图片描述
可以发现,hello threadhello world的执行顺序不确定,每次出现的次数也不确定(执行时间也不确定),这很好的印证了我们之前所说的随机调度或者是抢占式执行

可以使用的工具

Jdk中提供了一个工具Jconsole,可以用来观察线程的状态:
在这里插入图片描述
这就是我们刚才创建的两个线程Thread-0main,由于Java程序是运行在JVM虚拟机上的,JVM有一些垃圾回收、监控统计各种指标等功能,所以还存在一些别的线程。在这里插入图片描述

二、创建线程的方式

  1. 继承Thread类,重写run方法
class MyThread extends Thread{@Overridepublic void run() {System.out.println("hello");}
}public class ThreadDemo1 {public static void main(String[] args)  {MyThread t =new MyThread();t.start();}
}
  • Thread类实现了Runnable接口
  1. 实现Runnable接口,重写run方法
class MyThread implements Runnable{@Overridepublic void run() {System.out.println("hello");}
}public class ThreadDemo1 {public static void main(String[] args)  {Thread t =new Thread(new MyThread());t.start();}
}
  1. 继承Thread,重写run方法,使用匿名内部类
  • 匿名内部类,在一个类里面定义,写法简单,但没有名字,不能调用,只能使用一次。
public class ThreadDemo1 {public static void main(String[] args)  {//此处t指向的是Thread的子类,没有名字,故称为匿名内部类//匿名内部类内重写了run方法,实现一定的逻辑Thread t =new Thread(){@Overridepublic void run() {System.out.println("hello");}};t.start();}
}
  1. 实现Runnable接口,重写run方法,使用匿名内部类
public class ThreadDemo1  {public static void main(String[] args)  {Thread t=new Thread(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});t.start();}
}

5.λ表达式

public class ThreadDemo1  {public static void main(String[] args)  {Thread t=new Thread(()-> {System.out.println("hello");});t.start();}
}
  • λ表达式可以理解为是函数式的接口,不过这个函数也是匿名的
  • 如果要实现的逻辑比较简单,λ表达式是非常推荐使用的

其实λ表达式这种写法,相当于Runnable重写run方法。编译器在编译的时候,Thread构造方法有好几种,匹配到Runnable这个版本的时候,发现正好可以匹配上,而Runnable内部的run()没有参数,匹配到λ。(相当于是省略了方法名)

三、Thread类中重要的属性和方法

3.1 构造方法
构造方法说明
Thread()创建线程对象
Thread(Runnable target)使用实现了Runnable接口的对象创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target,String name)使用实现了Runnable接口的对象创建线程对象,并命名
Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("Just a name");
Thread t4 = new Thread(new MyRunnable(), "Just a name");
  • 如果没有命名,默认按照Thread-0,1,2,3的方式命名。
3.2 常见属性
属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程(守护线程)isDaemon()
是否存活isAlive()
是否被中断isInterrupted()
  1. 我们前面讲到进程的时候,说到进程有状态,比如就绪状态和阻塞状态,此处的线程也有状态,并且Java对线程的状态,进行了进一步的区分。
  2. 后台线程和前台线程的区别:前台线程的运行,会组织进程结束;后台线程的运行,不会阻止进程结束。默认创建前台线程。
public class ThreadDemo1  {public static void main(String[] args) throws InterruptedException {Thread t=new Thread() {@Overridepublic void run() {while (true) {System.out.println("hello");}}};//可以在线程启动前设置前台线程和后台线程t.setDaemon(true);//一个线程只能启动一次t.start();System.out.println("这是主线程,期望在t线程结束后打印");}
}
  1. 如何理解线程是否存活?
    简单的说,这里描述的是操作系统中这个线程是否被真正创建出来了。我们在代码中创建出线程对象后,此时系统中并没有真正创建出线程,需要我们调用start方法,系统中才能真正创建出线程,此时线程才是存活的。
public static void main(String[] args) throws InterruptedException {Thread t=new Thread(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});System.out.println("线程启动前"+t.isAlive());t.start();System.out.println("线程运行中"+t.isAlive());Thread.sleep(1000);System.out.println("线程运行结束"+t.isAlive());}

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

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

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

相关文章

IP转发流程

IP 转发是网络通信中通过中间设备(如路由器或启用了转发功能的主机)将接收到的 IP 数据包根据路由表的指引发送到目标网络的过程。以下是 IP 转发的详细流程及转发过程中各个环节的说明: IP 转发的流程详解 数据包到达路由器或主机&#xff…

Java技术复习提升 11 常用类

第11章 常用类 1 包装类 不同包装类都继承自Object类 Serialiazble接口表示该类表示序列化 Comparable接口用于定义自然顺序 包装类和基本数据的转换 jdk5之前手动装箱拆箱 jdk5之后自动装箱拆箱 自动装箱底层调用的是valueof方法 拆箱仍然是intvalue方法 public class Inte…

P1 练习卷(C++4道题)

1.纷繁世界 内存限制:256MB 时间限制:1s 问题描述 这是一个纷繁复杂的世界。 某一天清晨你起床很迟,没有吃上早饭。于是你骑着自行车去超市,但是你又发现商店的工作人员已经重新贴上了价格标签,零食价格都涨了50%。你…

STL之哈希

STL之哈希 unordered_set/map&哈希之介绍unordered系列哈希哈希表的模拟实现 unordered_set&/map的模拟实现哈希的应用位图(bitmap/bitset)布隆过滤器(Bloom Filter)海量数据处理 unordered_set/map&哈希之介绍 unor…

Selenium的八种定位方式

1. 通过 ID 定位 ID 是最直接和高效的方式来定位元素,因为每个页面中的 ID 应该是唯一的。 from selenium import webdriverdriver webdriver.Chrome(executable_pathpath/to/chromedriver) driver.get(https://example.com)# 通过 ID 定位 element driver.find…

logback动态获取nacos配置

文章目录 前言一、整体思路二、使用bootstrap.yml三、增加环境变量四、pom文件五、logback-spring.xml更改总结 前言 主要是logback动态获取nacos的配置信息,结尾完整代码 项目springcloudnacosplumelog,使用的时候、特别是部署的时候,需要改环境&#…

AwsCredentialsProvider认证接口

一、介绍 1、简介 AwsCredentialsProvider 是 AWS SDK 中用于提供 AWS 身份验证凭证的一个接口。AWS SDK 中涉及身份验证和授权的操作都需要用到凭证,而 AwsCredentialsProvider 作为一种抽象,负责提供这些凭证。AwsCredentialsProvider 在 Java SDK 中尤为重要,它可以用于…

OpenMM的安装与使用

技术背景 OpenMM是一款基于Python开发的开源分子动力学模拟软件,这几年因为AlphaFold的缘故,使得这个软件的热度有了不少提升。并且可以使用GPU硬件加速,所以性能上也不赖。这里介绍一下该软件的基本安装和使用方法,并附带一个真空…

R语言p值矫正整的方法

在 R 语言中&#xff0c;P 值的校正常用于控制多重假设检验中的错误率。以下是常用的 P 值校正方法及其实现方式&#xff1a; 1. p.adjust函数 R 提供了内置的 p.adjust 函数&#xff0c;支持多种校正方法&#xff1a; # 示例数据 p_values <- c(0.01, 0.02, 0.03, 0.04,…

Linux各种并发服务器优缺点

本文旨在介绍针对“无并发C/S模型”改进的方法总结以及各种改进方法的优缺点&#xff0c;具体函数的实现并不介绍。 1. 无并发C/S模型 创建服务器流程分析&#xff1a; socket()创建服务器的监听套接字bind()将服务器给服务器的监听套接字绑定IP地址和Port端口号listen()设置…

项目:从CSV文件中删除标题行

一、项目内容 打开当前工作目录中所有扩展名为.csv的文件&#xff0c;读取CSV文件的内容&#xff0c;并除掉第一行的内容以重新写入同名的文件。 二、代码分析 循环遍历从os.listdir()得到的文件列表&#xff0c;跳过非CSV文件。创建一个CSV reader对象来读取该文件的内容&a…

cookie反爬----普通服务器,阿里系

目录 一.常见COOKIE反爬 普通&#xff1a; 1. 简介 2. 加密原理 二.实战案例 1. 服务器响应cookie信息 1. 逆向目标 2. 逆向分析 2. 阿里系cookie逆向 1. 逆向目标 2. 逆向分析 实战&#xff1a; 无限debugger原理 1. Function("debugger").call() 2. …

网络无人值守批量装机-cobbler

网络无人值守批量装机-cobbler 一、cobbler简介 ​ 上一节中的pxe+kickstart已经可以解决网络批量装机的问题了,但是环境配置过于复杂,而且仅针对某一个版本的操作系统进批量安装则无法满足目前复杂环境的部署需求。 ​ 本小节所讲的cobbler则是基于pxe+kickstart技术的二…

推荐一款开源电子书阅读器Koodo Reader

Koodo Reader 是一个开源的电子书阅读器&#xff0c;支持多达15种主流电子书格式&#xff0c; 内置笔记、高亮、翻译功能&#xff0c;助力高效书籍阅读和学习。 官网地址&#xff1a;https://www.koodoreader.com/zh 一、下载软件 下载地址&#xff1a;https://dl.koodoreader.…

如何理解JS的 异步

JS是一门单线程的语言&#xff0c;这是因为它运行在浏览器的渲染主线程中&#xff0c;而渲染主线程只有一个。 而渲染主线程承担着诸多的工作&#xff0c;渲染页面、执行JS都在其中运行。 如果使用同步的方式&#xff0c;就极有可能导致主线程产生阻塞&#xff0c;从而导致消…

MySQL 数据库命名及SQL语句书写规范详解

MySQL 数据库命名及SQL语句书写规范详解 在软件开发过程中&#xff0c;数据库的设计与SQL语句的编写是确保系统性能和可维护性的关键因素。良好的命名规范和SQL语句书写规范不仅能提高代码的可读性和可维护性&#xff0c;还能有效减少潜在的错误。本文将详细介绍MySQL数据库中…

FreeRTOS——互斥信号量

一、为什么需要互斥信号量 前面的学习中&#xff1a; 调度锁、临界段不可避免的破坏了实时性&#xff0c;还有二值信号量存在这样的隐患——“优先级翻转” 优先级翻转 简单来说&#xff0c;就是由于信号量被低优先级任务占用&#xff0c;即使遇到高优先级任务&#xff0c;它…

11/19使用Spring,gradle实现前后端交互

创建 Gradle 项目 在你常用的 IDE&#xff08;如 Intellij IDEA&#xff09;中选择创建新的 Gradle 项目&#xff0c;按照向导进行相应的配置&#xff0c;选择合适的项目名称、目录等信息。配置 build.gradle 文件&#xff08;Gradle 项目的配置文件&#xff09;&#xff0c;添…

AIGC学习笔记(6)——AI大模型开发工程师

文章目录 AI大模型开发工程师005 OpenAI大模型案例实践1 AI 翻译助手需求分析项目起源市场价格和市场前景基于大模型的翻译软件核心功能设计 2 AI 翻译助手架构设计架构设计代码结构设计 3 AI 翻译助手核心功能文档解析文档操作PDF文档操作表格操作图片操作 Prompt封装 4 AI 翻…

程序语言语法上手题目合集

程序语言语法上手题目合集 1跑步2猜年龄3Vigenre 密码 1跑步 2.跑步 - 蓝桥云课 枚举日期&#xff0c;判断是否符合条件即可。 参考程序&#xff1a; #include<stdio.h> int y2022,m1,d1; int week6; int month[13]{0,31,28,31,30,31,30,31,31,30,31,30,31};int judg…