【JAVA进阶篇教学】第六篇:Java线程中状态

博主打算从0-1讲解下java进阶篇教学,今天教学第六篇:Java线程中状态。    

理解并掌握线程的休眠、停止和挂起等操作是多线程编程中的重要内容。下面我将详细说明这些操作,并提供相应的代码案例。

目录

一、线程休眠(Thread Sleep) 

二、线程停止(Thread Stop)

三、线程挂起(Thread Suspend 和 Thread Resume)

四、线程等待(Object Wait)

详细说明


一、线程休眠(Thread Sleep) 

Thread.sleep()方法可以在任何线程中调用,包括主线程和子线程。它可以用于模拟等待、暂停执行或者降低CPU消耗等场景。但是需要注意的是,Thread.sleep()方法会暂停当前线程的执行,因此应该确保不会在关键代码段中调用,以避免影响程序的正常运行。

在Java中,可以使用Thread.sleep()方法来使当前线程休眠一段时间。该方法接受一个毫秒数作为参数,表示线程休眠的时间。

public class ThreadSleepExample {
    public static void main(String[] args) {
        System.out.println("Main thread starts.");

        // 创建一个新线程并启动
        Thread thread = new Thread(new Worker());
        thread.start();

        // 主线程休眠3秒钟
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 主线程结束
        System.out.println("Main thread ends.");
    }

    static class Worker implements Runnable {
        @Override
        public void run() {
            System.out.println("Worker thread starts.");
            // Worker线程休眠2秒钟
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Worker thread ends.");
        }
    }
}

二、线程停止(Thread Stop)

线程停止通常应该由线程本身来控制。可以通过设置一个标志位来控制线程的执行状态,然后在适当的时机检查该标志位并退出线程。这样做可以保证线程的退出过程是安全和可控的。避免直接使用Thread.stop()方法来强制停止线程,因为这可能会导致线程处于不确定的状态,并可能导致数据不一致等问题。

在Java中,通常不推荐直接使用Thread.stop()方法来停止线程,因为这会导致线程处于不确定的状态,并且可能会导致数据不一致等问题。更安全的做法是使用标志位来控制线程的执行状态。

public class ThreadStopExample {
    private static volatile boolean running = true;

    public static void main(String[] args) {
        System.out.println("Main thread starts.");

        // 创建一个新线程并启动
        Thread thread = new Thread(new Worker());
        thread.start();

        // 主线程休眠3秒钟
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 停止Worker线程
        running = false;

        // 主线程结束
        System.out.println("Main thread ends.");
    }

    static class Worker implements Runnable {
        @Override
        public void run() {
            System.out.println("Worker thread starts.");
            while (running) {
                // 执行任务
            }
            System.out.println("Worker thread ends.");
        }
    }
}

三、线程挂起(Thread Suspend 和 Thread Resume)

Thread.suspend()和Thread.resume()方法已经被标记为废弃,不推荐使用。如果确实需要在某些情况下使用这些方法,应该在合适的时机调用,并且谨慎处理线程的挂起和恢复过程。需要注意的是,这些方法可能会导致线程死锁和数据不一致等问题,因此应该尽量避免使用。

在Java中,可以使用Thread.suspend()方法将线程挂起,使用Thread.resume()方法将线程恢复。但是,这两个方法已经被标记为废弃,因为它们可能导致线程死锁和数据不一致等问题,不推荐使用。

public class ThreadSuspendResumeExample {
    public static void main(String[] args) {
        System.out.println("Main thread starts.");

        // 创建一个新线程并启动
        Thread thread = new Thread(new Worker());
        thread.start();

        // 主线程休眠3秒钟
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 挂起Worker线程
        thread.suspend();
        System.out.println("Worker thread suspended.");

        // 主线程休眠3秒钟
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 恢复Worker线程
        thread.resume();
        System.out.println("Worker thread resumed.");

        // 主线程结束
        System.out.println("Main thread ends.");
    }

    static class Worker implements Runnable {
        @Override
        public void run() {
            System.out.println("Worker thread starts.");
            while (true) {
                // 执行任务
            }
        }
    }
}

尽管Thread.suspend()和Thread.resume()方法已经被标记为废弃,但是在某些特定的情况下,仍然可以使用它们。不过需要谨慎使用,以避免可能出现的问题。

四、线程等待(Object Wait)

在Java中,wait()方法是Object类的一个实例方法,用于让当前线程进入等待状态,同时释放对象的锁。当调用wait()方法时,当前线程会被挂起,直到其他线程调用了该对象的notify()或notifyAll()方法来唤醒它,或者等待指定的时间到达。

详细说明

  • 当调用wait()方法时,当前线程会进入对象的等待队列中,并释放对象的锁,允许其他线程访问该对象。
  • 调用wait()方法的线程会一直等待,直到被唤醒(通过notify()或notifyAll()方法),或者等待时间到达(如果提供了超时参数)。
  • 被唤醒的线程会重新进入对象的锁池中,等待获取对象的锁后继续执行。
  • 如果调用wait()方法的线程在等待过程中被中断,会抛出InterruptedException异常。

下面是一个使用wait()和notify()方法的示例,演示了如何实现简单的生产者-消费者模式:

public class ProducerConsumerExample {
    private static final int MAX_CAPACITY = 5;
    private static List<Integer> buffer = new ArrayList<>();

    public static void main(String[] args) {
        Thread producerThread = new Thread(new Producer());
        Thread consumerThread = new Thread(new Consumer());

        producerThread.start();
        consumerThread.start();
    }

    static class Producer implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (buffer) {
                    while (buffer.size() == MAX_CAPACITY) {
                        try {
                            buffer.wait(); // 缓冲区已满,生产者等待
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    int item = (int) (Math.random() * 100);
                    buffer.add(item);
                    System.out.println("Produced: " + item);

                    buffer.notifyAll(); // 唤醒所有消费者
                }
            }
        }
    }

    static class Consumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (buffer) {
                    while (buffer.isEmpty()) {
                        try {
                            buffer.wait(); // 缓冲区为空,消费者等待
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    int item = buffer.remove(0);
                    System.out.println("Consumed: " + item);

                    buffer.notifyAll(); // 唤醒所有生产者
                }
            }
        }
    }
}

在上面的示例中,生产者线程和消费者线程共享一个缓冲区buffer,当缓冲区为空时,消费者线程会调用wait()方法进入等待状态,直到生产者线程生产出新的数据并调用notifyAll()方法唤醒它。同样,当缓冲区已满时,生产者线程会调用wait()方法进入等待状态,直到消费者线程消费掉部分数据后调用notifyAll()方法唤醒它。

这样,通过使用wait()和notify()方法,可以实现生产者-消费者模式中的线程协作。

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

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

相关文章

一个早安寄语打卡的小程序技术分享

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 1.早起打卡还能赚钱&#xff1f; 是的&#xff0c;你没有听错&#xff0c;最近发现了个非常有意思的小程序&#xff0c;主要是让用户早起早睡&#xff0c;然后每天进行打卡操作的。 当然&…

【KG+RAG 论文】医学知识图谱检索增强 LLM 的框架 —— KG-RAG

论文&#xff1a;Biomedical knowledge graph-enhanced prompt generation for large language models ⭐⭐⭐ Code&#xff1a;github.com/BaranziniLab/KG_RAG 文章目录 论文速读模型效果总结 论文速读 这篇论文提出了 KG-RAG 的框架&#xff0c;使用医学知识图谱&#xff0…

黑马面试篇

课程地址&#xff1a;新版Java面试专题视频教程&#xff0c;java八股文面试全套真题深度详解&#xff08;含大厂高频面试真题&#xff09;_哔哩哔哩_bilibili 课程名称&#xff1a;新版Java面试专题视频教程&#xff0c;java八股文面试全套真题深度详解&#xff08;含大厂高频…

【Protobuf】protobuf详细介绍

protobuf详细介绍 一、前言二、Protobuf简介2.1、核心思想2.2、Protobuf是如何工作的&#xff1f;2.3、如何使用 Protoc 生成代码&#xff1f;2.4 入门命令 一、前言 在以往的项目中进行网络通信和数据交换的应用场景中&#xff0c;最经常使用的技术便是json或xml。随着JSON的…

用户中心 -- 插件使用 插件使用思路

易错注意点 1 5.1启动类 & 入口类 需保持一致 网址&#xff1a; 第一节课&#xff0c;用户管理--后端初始化&#xff0c;项目调通。二次翻工2-CSDN博客 一、 用户管理 框架 网址&#xff1a; 用户管理 --汇总 -- 明细-CSDN博客 1.2 更改路径&#xff0c;并生效 网址…

盘点那些你不知道的“痛”,柯桥俄语培训

首先我们来看一下болеть的五大含义&#xff1a; ①(чем 及无补语) 生病&#xff0c;患病 例&#xff1a; болеть тифом 害伤寒病 болеть воспалением лёгких 得肺炎 ②[只用第3人称] болит&#xff0c;болят 疼痛 例&am…

CDGA|数据治理新视角:清洗数据,让数据质量飞跃提升

在数据治理的新视角下&#xff0c;数据清洗不再是一个孤立的环节&#xff0c;而是与数据收集、存储、分析和应用紧密相连。它涉及到数据的全生命周期&#xff0c;从源头开始就对数据进行严格的把控。在数据收集阶段&#xff0c;通过设定合理的数据规范和校验机制&#xff0c;确…

DFS时间戳

时间戳 这就是树上查询问题 &#xff0c; 是求两个点有什么关系 让我们来看一下样例解释&#xff1a;注意字母旁边的数字就是时间戳&#xff0c; a在先序遍历&#xff08;遍历顺序 &#xff1a; 左&#xff0c;右&#xff0c;根&#xff09;是第一个进&#xff0c; 第十六个出…

#ESP32S3R8N8建立工程(VSCODE)点亮LED

1.参考文档 【立创ESP32S3R8N8】IDF入门手册 - 飞书云文档 (feishu.cn)https://lceda001.feishu.cn/wiki/GOIlwwfbIi1SC3k8594cDeFVn8g 2.建立工程 3.运行效果 4.更改配置 5.插播 之前配置的环境是有问题的&#xff0c;就算有自动检测也要仔细检查&#xff0c;必须严格按照以…

Linux内核广泛采用的侵入式数据结构设计

Linux内核广泛采用的侵入式数据结构设计恐怕很难应用到一般程序开发中。基本上是个高维十字链表&#xff0c;一个节点(struct)可以同时位于多个hash/list/tree中。我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪…

一键设置jdk环境脚本

自动化脚本 一、使用方法 创建一个txt文本&#xff0c;放在和jdk存放的同一目录下&#xff0c;复制粘贴进我的代码&#xff0c;利用全局替换&#xff0c;将jdk1.8,改成你自己的jdk包名字&#xff0c;再重新把这个文件保存为.vbs文件。然后运行就行了 MsgBox "Runing s…

邮件SMTP服务的性能怎么做优化?如何配置?

邮件SMTP服务的工作原理&#xff1f;邮件服务器发信的优势特点&#xff1f; 邮件SMTP服务作为信息传递的核心组件&#xff0c;其性能优化显得尤为关键。一个高效稳定的SMTP服务不仅能提升工作效率&#xff0c;还能保障信息安全。那么&#xff0c;邮件SMTP服务的性能怎么做优化…

Web漏扫工具OWASP ZAP安装与使用(非常详细)从零基础入门到精通,看完这一篇就够了。

本文仅用于安全学习使用&#xff01;切勿非法用途。 一、OWASP ZAP简介 开放式Web应用程序安全项目&#xff08;OWASP&#xff0c;Open Web Application Security Project&#xff09;是一个组织&#xff0c;它提供有关计算机和互联网应用程序的公正、实际、有成本效益的信息。…

MySQL数据库基础(数据库的基本操作、常用的数据类型、表的相关操作)

前言 今天我们将介绍数据库的基本操作、常用的数据类型、表的相关操作 一、数据库的基本操作 1.1 显示当前的数据库 操作代码 show databases;1.2 创建数据库 基本语法&#xff1a; 1. //创建数据库 create database examble;2. create database if not exists exist exa…

必应bing广告推广开户时间需要多久?

企业选择合适的平台进行广告投放成为了企业获取竞争优势的关键一步&#xff0c;必应Bing作为全球第二大搜索引擎&#xff0c;凭借其庞大的用户基础和精准的广告定位能力&#xff0c;成为了众多企业海外及国内市场推广的优选渠道。云衔科技以专业、高效的服务&#xff0c;成为企…

JMeter的下载安装与使用(Mac)

1、下载地址​​​​​​https://jmeter.apache.org/download_jmeter.cgi 2、下载Binaries 下的apache-jmeter5.5.tgz 3、解压 4、启动 在bin目录下打开终端&#xff0c;输入sh jmeter 出现jmeter首页界面&#xff0c;即为成功。 5、使用 5.1 语言选择 option选项卡&am…

新装电脑Flutter环境部署坑汇总(持续更新)

1.本地安装&#xff0c;安装fvm的坑 本人电脑使用windows &#xff0c;安装fvm则一般使用choco安装&#xff0c;那么首先需要安装choco,打开powershell/或者cmd运行以下命令&#xff1a; Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager…

Mycat(二)读写分离(Mysql读写分离->MyCat读写分离)、安装JDK

文章目录 概述搭建 MySQL 数据库主从复制MySQL 主从复制原理主机配置(atguigu01)从机配置(atguigu02)主机、从机重启 MySQL 服务主机从机都关闭防火墙在主机上建立帐户并授权 slave在从机上配置需要复制的主机主机新建库、新建表、insert 记录&#xff0c;从机复制停止从服务复…

Linux基本指令(2)

目录 mv指令&#xff1a; cat&#xff1a; more指令&#xff1a; less指令&#xff1a; head指令&#xff1a; tail指令&#xff1a; mv指令&#xff1a; 说明&#xff1a; mv命令是move的缩写&#xff0c;可以用来移动文件或者文件改名(move(rename)files),是linux系统下…

LMDeploy 量化部署 LLM-VLM 实践 学习笔记

视频链接 https://www.bilibili.com/video/BV1tr421x75B/?vd_sourcea1ce254b4a97f9f687a83e661793cb2c 什么是模型部署 部署指的是已经开发好的大模型投入使用&#xff0c;要把模型部署到服务器或者移动端里&#xff0c;如何在有限的资源里加载大模型&#xff1f; 比如你好不…
最新文章