Java SE入门及基础(59) 线程的实现(上) 线程的创建方式 线程内存模型 线程安全

目录

线程(上)

1. 线程的创建方式

Thread类常用构造方法

Thread类常用成员方法

Thread类常用静态方法

示例

总结

2. 线程内存模型

3.线程安全

案例

代码实现

执行结果


线程(上)

1. 线程的创建方式

        An application that creates an instance of Thread must provide the code that will run in that thread. There are two ways to do this:
        创建Thread 实例的应用程序必须提供将在该线程中运行的代码。 有两种方法可以做到这一点:
        -Provide a Runnable object. The Runnable interface defines a single method, run, meant to contain the code executed in the thread.
        -提供可运行的对象。 Runnable 接口定义了一个方法 run ,旨在包含在线程中执行的代码。
        -Subclass Thread. The Thread class itself implements Runnable, though its run method does nothing.
        -子类线程。 Thread 类本身实现了 Runnable ,尽管它的 run 方法不执行任何操作。
Thread类常用构造方法
public Thread (); // 创建一个线程
public Thread ( String name ); // 创建一个依据名称的线程
public Thread ( Runnable target ); // 根据给定的线程任务创建一个线程
public Thread ( Runnable target , String name ); // 根据给定的线程任务和名称创建一个线程
Thread类常用成员方法
public synchronized void start (); // 启动线程但不一定会执行
public final String getName (); // 获取线程名称
public final synchronized void setName ( String name ); // 设置线程的名称
public final void setPriority ( int newPriority ); // 设置线程的优先级
public final int getPriority (); // 获取线程的优先级
public final void join () throws InterruptedException ; // 等待线程执行完成
// 等待线程执行给定的时间 ( 单位毫秒 )
public final synchronized void join ( long millis ) throws
InterruptedException ;
// 等待线程执行给定的时间 ( 单位毫秒、纳秒 )
public final synchronized void join ( long millis , int nanos ) throws
InterruptedException ;
public long getId (); // 获取线程的 ID
public State getState (); // 获取线程的状态
public boolean isInterrupted (); // 检测线程是否被打断
public void interrupt (); // 打断线程
Thread类常用静态方法
public static native Thread currentThread (); // 获取当前运行的线程
public static boolean interrupted (); // 检测当前运行的线程是否被打断
public static native void yield (); // 暂停当前运行的线程,然后再与其他线程争抢资源,称
为线程礼让
// 使当前线程睡眠给定的时间(单位毫秒)
public static native void sleep ( long millis ) throws InterruptedException ;
// 使当前线程睡眠给定的时间(单位毫秒、纳秒)
public static void sleep ( long millis , int nanos ) throws
InterruptedException ;
示例
public class CreateDemo {
        public static void main ( String [] args ) {
                Thread t1 = new SubThread ( "inherit" ); // 通过继承实现的线程
                Thread t2 = new Thread ( new ThreadTask (), "interface" ); // 通过实现
                Runnable接口实现的线程
                t1 . start (); //start 方法只是告诉 JVM 线程 t1 已经准备好了,随时可以调度执行
                try {
                        t1 . join (); // 等待线程 t1 执行完成
                        t1 . join ( 1000 ); // 等待线程 t1 执行 1
                        // 1毫秒 = 1000微秒 = 1000000 纳秒
                        t1 . join ( 1000 , 50000 ); // 等待线程 t1 执行 1.5
                } catch ( InterruptedException e ) {
                        e . printStackTrace ();
                }
                t2 . start ();
        }
        static class SubThread extends Thread {
                public SubThread () {
                }
                public SubThread ( String name ) {
                        super ( name );
                }
                @Override
                public void run () {
                        try {
                                Thread . sleep ( 2000 );
                        } catch ( InterruptedException e ) {
                                e . printStackTrace ();
                        }
                        System . out . println ( getName () + "=>This is SubThread" );
                }
        }
        static class ThreadTask implements Runnable {
                @Override
                public void run () {
                        Thread thread = Thread . currentThread ();
                       String name = thread . getName ();
                        System . out . println ( name + "=>This is Implementation" );
                }
        }
}
总结
        创建线程有两种方式:实现 Runable 接口和继承 Thread 。相较于继承 Thread ,实现 Runable 接口更具有优势,在实现接口的同时还可以继承自其他的父类,避免了Java 中类单继承的局限性;同时Runable 接口的实现可以被多个线程重用,但继承 Thread 无法做到;后续学到的线程池中支持Runable 接口但不支持 Thread

2. 线程内存模型

3.线程安全

案例
某火车站有 10 张火车票在 3 个窗口售卖
代码实现
public class SaleThreadTest {
        public static void main ( String [] args ) {
                SaleTask task = new SaleTask ();
                Thread t1 = new Thread ( task , " 窗口 1" );
                Thread t2 = new Thread ( task , " 窗口 2" );
                Thread t3 = new Thread ( task , " 窗口 3" );
                t1 . start ();
                t2 . start ();
                t3 . start ();
        }
static class SaleTask implements Runnable {
        private int totalTickets = 10 ; // 售卖 10 张火车票
        @Override
        public void run () {
                while ( true ){
                        String name = Thread . currentThread (). getName ();
                        System . out . println ( name + " 售卖火车票: " + totalTickets );
                        totalTickets -- ;
                        if ( totalTickets <= 0 ) break ;
                                try {
                                        Thread . sleep ( 100L );
                                } catch ( InterruptedException e ) {
                                        e . printStackTrace ();
                                }
                        }
                }
        }
}
执行结果

从结果中可以看出,同一张火车票被卖了多次,这是由于线程之间获取信息不同步导致。

更多参考:

Java SE入门及基础(60)& 线程的实现(下) & 线程的同步(synchronized 和 Lock 的实现) & 线程通信 & 线程状态-CSDN博客

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

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

相关文章

利用 Docker 简化 Nacos 部署:快速搭建 Nacos 服务

利用 Docker 简化 Nacos 部署&#xff1a;快速搭建 Nacos 服务 引言 在微服务架构中&#xff0c;服务注册与发现是确保服务间通信顺畅的关键组件。Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;作为阿里巴巴开源的一个服务发现和配置管理平台&…

任务调度器——任务切换

一、开启任务调度器 函数原型&#xff1a; void vTaskStartScheduler( void ) 作用&#xff1a;用于启动任务调度器&#xff0c;任务调度器启动后&#xff0c; FreeRTOS 便会开始进行任务调度 内部实现机制&#xff08;以动态创建为例&#xff09;&#xff1a; &#xff0…

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 下载页 ->Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人…

测评推荐:企业管理u盘的软件有哪些?

U盘作为一种便携的存储设备&#xff0c;方便易用&#xff0c;被广泛应用于企业办公、个人学习及日常工作中。然而&#xff0c;U盘的使用也带来了数据泄露、病毒传播等安全隐患。为了解决这些问题&#xff0c;企业管理U盘的软件应运而生。 本文将对市面上流行的几款U盘管理软件…

Hadoop3:Yarn容量调度器配置多队列案例

一、情景描述 需求1&#xff1a; default队列占总内存的40%&#xff0c;最大资源容量占总资源60%&#xff0c;hive队列占总内存的60%&#xff0c;最大资源容量占总资源80%。 二、多队列优点 &#xff08;1&#xff09;因为担心员工不小心&#xff0c;写递归死循环代码&#…

电路笔记(电源模块): 基于FT2232HL实现的jtag下载器硬件+jtag的通信引脚说明

JTAG接口说明 JTAG 接口根据需求可以选择20针或14针的配置&#xff0c;具体选择取决于应用场景和需要连接的功能。比如之前的可编程逻辑器件XC9572XL使用JTAG引脚&#xff08;TCK、TDI、TDO、TMS、VREF、GND&#xff09;用于与器件进行调试和编程通信。更详细的内容可以阅读11…

51单片机STC8H8K64U通过RA8889/RA8876如何控制彩屏(SPI源码下载)

【硬件部份】 一、硬件连接实物&#xff1a; STC8H系列单片机不需要外部晶振和外部复位&#xff0c;在相同的工作频率下&#xff0c;速度比传统的8051单片机要快12倍&#xff0c;具有高可靠抗干扰的优秀特性&#xff0c;与瑞佑的RA8889/RA8876控制芯片刚好可以完美搭配用于工…

redis实战-缓存雪崩问题及解决方案

定义理解 缓存雪崩是指在同一时间段&#xff0c;大量缓存的key同时失效&#xff0c;或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力 和缓存击穿的区别&#xff1a; 缓存雪崩是由于缓存中的大量数据同时失效或缓存服务器故障引起的&#xff1b…

机器学习周记(第四十五周:Graphformer)2024.6.24~2024.6.30

目录 摘要ABSTRACT1 论文信息1.1 论文标题1.2 论文摘要1.3 论文引言1.4 论文贡献 2 论文模型2.1 问题定义2.2 模型架构2.2.1 自注意下采样模块&#xff08;Self-attention down-sampling module&#xff09;2.2.2 稀疏图自注意力机制&#xff08;Sparse graph self-attention m…

【C++】using namespace std 到底什么意思

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文作为 JohnKi 的学习笔记&#xff0c;引用了部分大佬的案例 &#x1f4e2;未来很长&a…

新手练习项目 7:猜数字游戏

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#xff09; 目录 一、项目描述二、项目实现三、项目步骤四、项目扩展方向 更多项目内容&#xff0c;请关注我、订…

打靶记录——靶机medium_socnet

靶机下载地址 https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 打靶过程 由于靶机和我的Kali都处于同一个网段&#xff0c;所以使用arpscan二次发现技术来识别目标主机的IP地址 arpscan -l除了192.168.174.133&#xff0c;其他IP都是我VMware虚拟机正…

【Spring Boot】认识 JPA 的接口

认识 JPA 的接口 1.JPA 接口 JpaRepository2.分页排序接口 PagingAndSortingRepository3.数据操作接口 CrudRepository4.分页接口 Pageable 和 Page5.排序类 Sort JPA 提供了操作数据库的接口。在开发过程中继承和使用这些接口&#xff0c;可简化现有的持久化开发工作。可以使 …

springboot学习,如何用redission实现分布式锁

目录 一、springboot框架介绍二、redission是什么三、什么是分布式锁四、如何用redission实现分布式锁 一、springboot框架介绍 Spring Boot是一个开源的Java框架&#xff0c;由Pivotal团队&#xff08;现为VMware的一部分&#xff09;于2013年推出。它旨在简化Spring应用程序…

大数据面试题之Spark(1)

目录 Spark的任务执行流程 Spark的运行流程 Spark的作业运行流程是怎么样的? Spark的特点 Spark源码中的任务调度 Spark作业调度 Spark的架构 Spark的使用场景 Spark on standalone模型、YARN架构模型(画架构图) Spark的yarn-cluster涉及的参数有哪些? Spark提交jo…

编码大模型系列:Meta创新的“代码编译优化”的LLM

鲁班号导读正式上线。移步“鲁班秘笈”&#xff0c;查阅更多内容。 大型语言模型 (LLM) 已在各种软件工程和编码任务中展现出卓越的能力。然而&#xff0c;它们在代码和编译器优化领域的应用仍未得到充分探索。训练LLM需要大量资源&#xff0c;需要大量的 GPU时间和大量的数据…

一个合理的前端应用文件结构

在大型应用中&#xff0c;最关键且最具挑战性的方面之一就是拥有一个良好且合理的文件结构。在考虑通过微前端将代码库拆分成多个应用之前&#xff0c;可以遵循一些步骤来改善项目级别的架构&#xff0c;并在您考虑这一路径时使过渡更容易。 我们的目标是应用某种模块化方法&am…

MSPM0G3507——定时器例程讲解4——timx_timer_mode_periodic

以下示例以周期模式配置TimerG并切换LED。周期从500ms开始&#xff0c;每次切换减少50ms&#xff0c;直到周期为100ms&#xff0c;然后重复。设备在等待中断时保持待机模式 #include "ti_msp_dl_config.h"/* ((32KHz / (321)) * 0.5s) 45 - 1 495 due to N1 ticks …

Qt中用QLabel创建状态灯

首先ui设计中分别创建了4个大灯和4个小灯。 编辑.h文件 #ifndef LED_H #define LED_H#include <QWidget> #include <QLabel>QT_BEGIN_NAMESPACE namespace Ui { class Led; } QT_END_NAMESPACEclass Led : public QWidget {Q_OBJECTpublic:Led(QWidget *parent n…

服务器硬件以及RAID配置

目录 一、RAID磁盘阵列原理&#xff08;嘎嘎重要&#xff09; 1、RAID的概述 2、常用的RAID 2.1、RAID 0 2.2、RAID 1 2.3、RAID 5 2.5、RAID 10 3、阵列卡介绍 二、建立软件RAID磁盘阵列 1、添加硬盘 2、使用fdisk分区&#xff0c;类型为fd 3、mdata命令使用参数 …