多线程基础:让你的程序跑得更快、更高效!

举报
喵手 发表于 2025/06/09 16:17:01 2025/06/09
【摘要】 开篇语哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,...

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在现代应用中,尤其是在高并发的场景下,多线程编程是一个非常强大且必不可少的技术。它让我们能够同时执行多个任务,提高程序的执行效率和响应能力。今天,我们将一起学习多线程的基础,包括如何创建和启动线程、线程的生命周期、线程优先级与调度机制,以及 Thread.sleep()Thread.yield() 的使用。


一、创建与启动线程:Thread 类与 Runnable 接口

Java 中创建和启动线程的方式主要有两种:继承 Thread 类和实现 Runnable 接口。这两种方式都可以用于定义和启动线程。

1.1 继承 Thread

当你需要创建一个线程时,可以通过继承 Thread 类并重写其 run() 方法来定义线程要执行的任务。

代码示例:继承 Thread 类创建线程
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程正在执行...");
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start(); // 启动线程
    }
}

  在这个例子中,MyThread 类继承了 Thread 类并重写了 run() 方法。在 main() 方法中,我们通过调用 start() 方法启动线程。注意,start() 方法会调用 run() 方法,但 run() 方法本身不会自动执行。

1.2 实现 Runnable 接口

另一种创建线程的方式是实现 Runnable 接口,并将其作为参数传递给 Thread 类的构造函数。这种方法适合那些已经继承了其他类的类,因为 Java 不支持多重继承。

代码示例:实现 Runnable 接口创建线程
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程正在执行...");
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start(); // 启动线程
    }
}

  在这个例子中,MyRunnable 实现了 Runnable 接口,并重写了 run() 方法。在 main() 方法中,我们将 MyRunnable 的实例传递给 Thread 构造函数,然后调用 start() 方法启动线程。


二、线程的生命周期

线程的生命周期描述了一个线程从创建到终止的各个状态。线程的生命周期包括以下几个状态:

  1. 新建(New):线程被创建后,还没有开始执行。
  2. 就绪(Runnable):线程已经准备好,可以被调度执行,但可能被操作系统暂时挂起。
  3. 运行(Running):线程正在执行。
  4. 阻塞(Blocked):线程因为某种原因(如等待 I/O 操作)被挂起,等待某些条件满足后才能继续。
  5. 死亡(Dead):线程的 run() 方法执行完毕,线程终止。

2.1 线程状态示意图

   New  --->  Runnable  --->  Running ---> Blocked --->  Dead

  线程的状态转换是由 Java 虚拟机(JVM)和操作系统的调度机制来控制的。在运行过程中,线程可能会经历阻塞、就绪、运行等状态的转换。


三、线程优先级与调度

线程优先级用于告诉操作系统哪个线程应该优先执行。Java 提供了 Thread 类的方法来设置和获取线程的优先级。线程优先级的值通常是从 1 到 10,其中 10 是最高优先级。

3.1 设置线程优先级

线程优先级通过 Thread.setPriority(int priority) 方法进行设置。默认情况下,线程的优先级是 5。

代码示例:设置线程优先级
public class ThreadPriorityExample {
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            System.out.println("线程1正在执行...");
        });

        Thread thread2 = new Thread(() -> {
            System.out.println("线程2正在执行...");
        });

        thread1.setPriority(Thread.MIN_PRIORITY); // 设置最低优先级
        thread2.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级

        thread1.start();
        thread2.start();
    }
}

  在这个例子中,我们创建了两个线程,并分别将它们的优先级设置为最低和最高优先级。Thread.MIN_PRIORITYThread.MAX_PRIORITYThread 类中的常量,表示线程的最低和最高优先级。

3.2 线程调度

线程调度是由操作系统的线程调度器决定的,通常基于线程的优先级、等待时间、CPU 可用性等因素。线程优先级越高,操作系统越倾向于优先调度该线程执行。


四、Thread.sleep()Thread.yield()

4.1 Thread.sleep()

Thread.sleep(long millis) 方法用于让当前线程暂停执行指定的时间。它可以用来实现线程的定时操作或者让线程在一定时间内不占用 CPU。

  • sleep() 会让当前线程进入“阻塞”状态,暂停指定的时间,然后重新进入“就绪”状态。
  • sleep() 方法不会释放锁,因此如果线程在持有锁时调用 sleep(),其他线程仍然不能访问该锁。
代码示例:使用 Thread.sleep()
public class ThreadSleepExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                System.out.println("线程开始...");
                Thread.sleep(2000);  // 线程暂停 2 秒
                System.out.println("线程结束...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread.start();
    }
}

  在这个例子中,线程将在打印“线程开始…”之后暂停 2 秒,然后继续执行。

4.2 Thread.yield()

Thread.yield() 方法用于让当前线程放弃对 CPU 的控制,允许同优先级的其他线程获得执行机会。调用 yield() 后,当前线程并不会完全停止,它会回到“就绪”状态,由调度器决定何时继续执行。

代码示例:使用 Thread.yield()
public class ThreadYieldExample {
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程1执行:" + i);
                Thread.yield();  // 放弃 CPU 使用权
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程2执行:" + i);
            }
        });

        thread1.start();
        thread2.start();
    }
}

  在这个例子中,thread1 在每次循环时调用 yield(),使得它放弃当前的 CPU 时间,允许其他线程(如 thread2)有机会执行。yield() 是一种轻量级的线程调度方式,适用于希望进行线程协作的场景。


总结:多线程编程的关键概念

  多线程编程是一项非常强大的技术,它能够提升程序的并发能力和执行效率。通过 Thread 类和 Runnable 接口,我们可以创建并启动线程;通过合理地设置线程的优先级和调度,我们可以优化线程的执行顺序;而 Thread.sleep()Thread.yield() 则提供了更多的线程控制方式,帮助我们在多线程环境下实现更高效的资源利用。

  掌握多线程基础,你将能够更好地应对复杂的并发任务和高效的程序设计!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。