【线程】Java多线程编程

news2024/11/24 23:31:01

【线程】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{
    @Override
    public 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{
    @Override
    public 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{
    @Override
    public 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(){
            @Override
            public 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() {
            @Override
            public 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() {
            @Override
            public 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() {
            @Override
            public 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.coloradmin.cn/o/2246946.html

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

相关文章

unsloth vlm模型Qwen2-VL、Llama 3.2 Vision微调案例

T4卡15G显卡训练 参考: https://github.com/unslothai/unsloth 按自己显卡cuda版本安装 免费colab微调代码: Qwen2-VL: https://colab.research.google.com/drive/1whHb54GNZMrNxIsi2wm2EY_-Pvo2QyKh?usp=sharing from unsloth import FastVisionModel # NEW instead …

window11编译pycdc.exe

一、代码库和参考链接 在对python打包的exe文件进行反编译时,会使用到uncompyle6工具,但是这个工具只支持python3.8及以下,针对更高的版本的python则不能反编译。 关于反编译参考几个文章: Python3.9及以上Pyinstaller 反编译教…

oracle如何配置第二个监听优化数据传输

oracle如何配置第二个监听优化数据传输 服务器两个网卡,配置两个不同IP和端口的监听。 归档日志量每天很大,为了不影响业务,需要配置一个单独的万兆网络来专门的传输归档日志到DG库,这里就涉及到在19c中增加一个监听用来使用专门…

Kafka Stream实战教程

Kafka Stream实战教程 1. Kafka Streams 基础入门 1.1 什么是 Kafka Streams Kafka Streams 是 Kafka 生态中用于 处理实时流数据 的一款轻量级流处理库。它利用 Kafka 作为数据来源和数据输出,可以让开发者轻松地对实时数据进行处理,比如计数、聚合、…

用 Python 从零开始创建神经网络(九):反向传播(Backpropagation)

反向传播(Backpropagation) 引言1. 分类交叉熵损失导数(Categorical Cross-Entropy loss derivative)2. 分类交叉熵损失导数 - 代码实现3. Softmax激活函数导数(Softmax activation derivative)4. Softmax激…

TCP vs UDP:如何选择适合的网络传输协议?

在网络通信中,TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)是两种非常重要的传输层协议。它们各有特点,适用于不同类型的应用场景。本文将详细探讨TCP和UDP协议的结构、优缺点及应用&…

06、Spring AOP

在我们接下来聊Spring AOP之前我们先了解一下设计模式中的代理模式。 一、代理模式 代理模式是23种设计模式中的一种,它属于结构型设计模式。 对于代理模式的理解: 程序中对象A与对象B无法直接交互,如:有人要找某个公司的老总得先打前台登记传达程序中某个功能需要在原基…

递归算法专题一>Pow(x, n)

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public double myPow(double x, int n) {return n < 0 ? 1.0 / pow(x,-n) : pow(x,n); }private double pow(double x, int n){if(n 0) return 1.0;double tmp pow(x,n / 2);return n % 2 0 ? tmp * tmp : tmp …

游戏引擎学习第20天

视频参考:https://www.bilibili.com/video/BV1VkBCYmExt 解释 off-by-one 错误 从演讲者的视角&#xff1a;对代码问题的剖析与修复过程 问题的起因 演讲者提到&#xff0c;他可能无意中在代码中造成了一个错误&#xff0c;这与“调试时间标记索引”有关。他发现了一个逻辑问题…

C语言:操作符详解1

一.操作符的分类 算术操作符&#xff1a;、-、* 、 /、% 移位操作符&#xff1a;<< >> 位操作符&#xff1a;& | ^ 赋值操作符&#xff1a; 、、-、*、/、%、<<、>>、&、|、^ 单目操作符&#xff1a;!、、--、&、*、、-、~、sizeo…

Harbor2.11.1生成自签证和配置HTTPS访问

文章目录 HTTPS的工作流程部署Harbor可参考上一篇文章生成自签证书1.修改/etc/hosts文件2.生成证书a.创建存放证书路径b.创建ca.key密钥c.创建ca.crtd.创建给Harbor服务器使用密钥 yunzhidong.harbor.com.keye.创建给Harbor服务器使用证书签名请求文件 yunzhidong.harbor.com.c…

c++--------《set 和 map》

c--------《set 和 map》 1 set系列的使⽤1.1 set类的介绍1.2 set的构造和迭代器1.3 set重要接口 2 实现样例2.1: insert和迭代器遍历使⽤样例&#xff1a;2.2: find和erase使⽤样例&#xff1a; 练习3.map系列的使用3.1 map类的介绍3.1.1 pair类型介绍 3.2 map的数据修改3.3mu…

分布式系统稳定性建设-性能优化篇

分布式系统稳定性建设-性能优化篇 系统稳定性建设是系统工程的核心内容之一。以下是一些重要的方面: 架构设计: 采用模块化、松耦合的架构设计,以提高系统的可扩展性和可维护性。合理划分系统功能模块,降低单个模块的复杂度。定义清晰的接口和数据交换标准,确保各模块之间协调…

应急响应靶机——linux2

载入虚拟机&#xff0c;打开虚拟机&#xff1a; 居然是没有图形化界面的那种linux&#xff0c;账户密码&#xff1a;root/Inch957821.&#xff08;注意是大写的i还有英文字符的.&#xff09; 查看虚拟机IP&#xff0c;192.168.230.10是NAT模式下自动分配的 看起来不是特别舒服&…

08 —— Webpack打包图片

【资源模块 | webpack 中文文档 | webpack中文文档 | webpack中文网】https://www.webpackjs.com/guides/asset-modules/?sid_for_share99125_3 Webpack打包图片以8KB为临界值判断 大于8KB的文件&#xff1a;发送一个单独的文件并导出URL地址 小于8KB的文件&#xff1a;导出一…

003 STM32基础、架构以及资料介绍——常识

注&#xff1a; 本笔记参考学习B站官方视频教程&#xff0c;免费公开交流&#xff0c;切莫商用。内容可能有误&#xff0c;具体以官方为准&#xff0c;也欢迎大家指出问题所在。 01什么是STM32&#xff08;宏观&#xff09; STM32属于一个微控制器&#xff0c;自带了各种常用通…

QT基础 窗体 对话框 文件 QT5.12.3环境 C++实现

一、堆栈窗体 1. 概念 是一种界面设计思路&#xff0c; 多个窗体重叠在一起&#xff0c;通过点击对应的按钮&#xff0c;显示对应的界面。 2. 相关方法 Public FunctionsQStackedWidget(QWidget * parent 0)//stack如果单纯指定父窗口&#xff0c;但是没有指定大小&#xf…

实践指南:EdgeOne与HAI的梦幻联动

在当今快速发展的数字时代&#xff0c;安全和速度已成为网络服务的基石。EdgeOne&#xff0c;作为腾讯云提供的边缘安全加速平台&#xff0c;以其全球部署的节点和强大的安全防护功能&#xff0c;为用户提供了稳定而高效的网络体验。而HAI&#xff08;HyperApplicationInventor…

【H2O2|全栈】JS进阶知识(六)ES6(2)

目录 前言 开篇语 准备工作 Set和Map 基本概念 Set 相互转化 常见属性和API 数组去重 并集、交集和差集 Map 转化 常见的属性和API Set和Map的区别 This的指向 function函数 箭头函数 修改this 使用方式 三种方式的异同 案例 更改this指向为obj 求数组数…

Redis配置主从架构、集群架构模式 redis主从架构配置 redis主从配置 redis主从架构 redis集群配置

Redis配置主从架构、集群架构模式 redis主从架构配置 redis主从配置 redis主从架构 redis集群配置 1、主从模式1.1、主节点配置1.2、从节点配置1.3、测试 2、集群模式 1、主从模式 1.1、主节点配置 # 监听所有网络接口 bind 0.0.0.0# cluster-enabled表示为集群模式&#xff…