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"

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

相关推荐
zhangfeng1133几秒前
openclaw skills 小龙虾技能 通讯仿真 matlab skill Simulink Agentic Toolkit,通过kimi找到,mcp通讯
开发语言·matlab·openclaw·通讯仿真
Javatutouhouduan6 小时前
2026Java面试的正确打开方式!
java·高并发·java面试·java面试题·后端开发·java编程·java八股文
chao1898447 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
JAVA面经实录9177 小时前
Java初级最终完整版学习路线图
java·spring·eclipse·maven
赏金术士7 小时前
Kotlin 习题集 · 高级篇
android·开发语言·kotlin
Cat_Rocky8 小时前
k8s-持久化存储,粗浅学习
java·学习·kubernetes
楼兰公子8 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
知识领航员8 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
吴声子夜歌8 小时前
Go——并发编程
开发语言·后端·golang
释怀°Believe8 小时前
Spring解析
java·后端·spring