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"

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

相关推荐
啾啾Fun5 分钟前
Java反射操作百倍性能优化
java·性能优化·反射·缓存思想
20岁30年经验的码农12 分钟前
若依微服务Openfeign接口调用超时问题
java·微服务·架构
曲莫终20 分钟前
SpEl表达式之强大的集合选择(Collection Selection)和集合投影(Collection Projection)
java·spring boot·spring
ajassi200038 分钟前
开源 java android app 开发(十二)封库.aar
android·java·linux·开源
q5673152344 分钟前
Java使用Selenium反爬虫优化方案
java·开发语言·分布式·爬虫·selenium
kaikaile19951 小时前
解密Spring Boot:深入理解条件装配与条件注解
java·spring boot·spring
守护者1701 小时前
JAVA学习-练习试用Java实现“一个词频统计工具 :读取文本文件,统计并输出每个单词的频率”
java·学习
bing_1581 小时前
Spring Boot 中ConditionalOnClass、ConditionalOnMissingBean 注解详解
java·spring boot·后端
ergdfhgerty1 小时前
斐讯N1部署Armbian与CasaOS实现远程存储管理
java·docker
勤奋的知更鸟1 小时前
Java性能测试工具列举
java·开发语言·测试工具