JavaEE-多线程实战01

Java 多线程入门:第一个多线程程序

在 Java 中,多线程编程是非常重要的一部分。本篇文章将通过示例,带你快速了解如何创建第一个多线程程序,并深入分析其运行机制。


1. 创建一个线程类并继承 Thread

在 Java 中,我们可以通过继承 Thread 类并重写其中的 run() 方法,来定义一个自己的线程行为。

来看第一个示例:

java 复制代码
package thread.test;

//1.创建一个自己的类,继承自这个Thread
class MyThread extends Thread {

    @Override
    public void run() {
        //run方法就是这个线程的入口方法,类似于main()
        System.out.println("hello world");
    }
}

public class ThreadDemo1 {
    public static void main(String[] args) {
        //2.根据自定义的类创建出实例(线程实例才是真正的线程)
        //也可以用MyThread t=new MyThread();
        Thread thread=new MyThread();
        //3.调用Thread的start方法,才会真正调用系统api,在系统内核中创建出线程
        //使用Thread会创建出线程,而直接使用run的话就不会
        thread.start();
        
    }
}

运行结果

2. 代码分析

当你调用 thread.start() 时,真正开辟了一个新的线程 ,系统会去执行 MyThread 类的 run() 方法里的代码(即打印 "hello world")。

注意,调用的是 start() 方法,而不是直接调用 run(),这是两者最关键的区别!

  • start() 方法通知系统启动一个新线程,不会阻塞当前主线程。

  • run() 方法只是一个普通的方法调用,不会开启新的线程。

所以,main() 方法会快速执行完,而子线程仍在后台执行。主线程和子线程各自独立运行。


3. 再举一个例子:多线程并发执行

来看另一个简单示例,理解并发执行的效果:

java 复制代码
public class Example {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
        System.out.println("main线程结束了");
    }
}
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("我是子线程");
    }
}

可能输出结果是:

也可能输出的结果是:

为什么会有两种可能?

因为多线程执行是并发 的,谁先执行完是不确定的,由操作系统线程调度器决定。


4. 小知识:守护线程(Daemon Thread)

在 Java 中,普通线程 会阻止整个程序结束。而守护线程 不会。
整个进程(整个程序)是不是结束,要看有没有别的 非守护线程 还在运行

具体来说:

  • 如果还有其他普通线程(非守护线程) 在运行,进程不会结束

  • 只有当所有非守护线程都结束以后,整个 Java 进程才真正结束。

  • 守护线程(daemon thread) 不会阻止进程结束(守护线程就像后台服务一样,进程结束了它也跟着挂了)。

如果你希望让子线程是**"守护线程"**,可以这样写:

java 复制代码
MyThread thread = new MyThread();
thread.setDaemon(true);  // 设置成守护线程
thread.start();

这样,当主线程执行完毕后,即使子线程还没跑完,整个进程也会直接结束

注意:setDaemon(true) 必须在 start() 之前调用,否则会抛异常!


Java 多线程入门:第二个多线程程序

接下来,我们来写一个持续运行的线程,看看主线程和子线程如何同时运行、轮流输出内容。


5. 代码示例:两个线程同时输出内容

java 复制代码
package thread.test;

class MyThread2 extends Thread {
    @Override
    public void run() {
        while (true) {
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        Thread t=new MyThread2();
        t.start();

        while (true) {
            System.out.println("hello main");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

执行结果

代码分析

6. 代码分析

  • MyThread2 是一个自定义线程类,重写了 run() 方法。

  • 子线程每隔 1 秒输出一次 "hello thread"

  • 主线程(main 方法)每隔 1 秒输出一次 "hello main"

运行效果示例:

由于是两个独立的线程,它们的输出顺序和精确时间点可能不一样,比如:

有时先看到 "hello main"

有时先看到 "hello thread"

这种不确定性就是并发执行的本质特征!

相关推荐
小钊(求职中)几秒前
ElasticSearch从入门到精通-覆盖DSL操作和Java实战
java·大数据·elasticsearch·搜索引擎·全文检索
席万里6 分钟前
Go语言企业级项目使用dlv调试
服务器·开发语言·golang
jerry60923 分钟前
c++流对象
开发语言·c++·算法
fmdpenny23 分钟前
用python写一个相机选型的简易程序
开发语言·python·数码相机
极客智谷25 分钟前
深入理解Java线程池:从原理到实战的完整指南
java·后端
代码不行的搬运工33 分钟前
HTML快速入门-4:HTML <meta> 标签属性详解
java·前端·html
海盗强1 小时前
Babel、core-js、Loader之间的关系和作用全解析
开发语言·前端·javascript
猿榜编程1 小时前
python基础-requests结合AI实现自动化数据抓取
开发语言·python·自动化
mask哥1 小时前
详解最新链路追踪skywalking框架介绍、架构、环境本地部署&配置、整合微服务springcloudalibaba 、日志收集、自定义链路追踪、告警等
java·spring cloud·架构·gateway·springboot·skywalking·链路追踪
XU磊2601 小时前
javaWeb开发---前后端开发全景图解(基础梳理 + 技术体系)
java·idea