【从零开始学习JAVA | 第三十八篇】应用多线程

这篇具有很好参考价值的文章主要介绍了【从零开始学习JAVA | 第三十八篇】应用多线程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

多线程的实现方式:

Thread常见的成员方法:

总结:


前言:

           多线程的引入不仅仅是提高计算机处理能力的技术手段,更是适应当前时代对效率和性能要求的必然选择。在本文中,我们将深入探讨多线程的应用和实践,帮助读者更好地理解和应用多线程技术,提升计算机的处理能力,迎接挑战的世界。"

【从零开始学习JAVA | 第三十八篇】应用多线程,【从零开始学习JAVA】,学习,java,线程,多线程,高并发

多线程的实现方式:

        1.继承Thread类:你可以创建一个类并继承Thread类,然后重写run()方法,在run()方法中定义线程要执行的任务。通过创建该类的实例,并调用start()方法,可以启动一个新的线程执行run()方法中的任务。

示例代码:

class MyThread extends Thread {
    public void run() {
        // 定义线程要执行的任务
        System.out.println("线程执行任务");
    }
}

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

        2.实现Runnable接口:你可以创建一个类实现Runnable接口,然后实现run()方法,再通过创建Thread对象,并将Runnable对象作为参数传递给Thread的构造函数,创建一个新的线程。

示例代码:

class MyRunnable implements Runnable {
    public void run() {
        // 定义线程要执行的任务
        System.out.println("线程执行任务");
    }
}

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

        3.使用Executor框架:Java提供了Executor框架,它是高级线程管理的一种方式。通过Executor,你可以使用线程池来管理和执行多个线程任务,提供更好的线程控制和资源管理。

示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainClass {
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 提交任务
        executor.execute(new Runnable(){
            public void run() {
                // 定义线程要执行的任务
                System.out.println("线程执行任务");
            }
        });

        // 关闭线程池
        executor.shutdown();
    }
}

         4.使用Callable 和 Future 接口方式实现:当需要在线程执行完毕后获取返回结果时,可以使用Callable和Future接口来实现多线程。Callable是一个带有返回结果的任务,可以通过call()方法执行任务并返回结果。Future表示一个异步执行的任务,可以通过get()方法获取任务的返回结果。

这种方式的优点就在于:可以获取多线程的执行结果 

示例代码:



class MyCallable implements Callable<Integer> {
    public Integer call() throws Exception {
        // 定义线程要执行的任务,并返回结果
        return 42;
    }
}

public class MainClass {
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executor = Executors.newSingleThreadExecutor();

        // 提交Callable任务
        Future<Integer> future = executor.submit(new MyCallable());

        // 等待并获取结果
        try {
            Integer result = future.get();
            System.out.println("线程执行任务的结果为: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 关闭线程池
        executor.shutdown();
    }
}

Thread常见的成员方法:

  • start(): 启动线程,使线程进入可运行状态,具体执行由操作系统调度。
  • run(): 线程执行的任务代码,通常通过重写该方法来定义线程要执行的逻辑。
  • sleep(long millis): 让当前线程休眠指定的毫秒数,暂停线程的执行。
  • join(): 等待线程执行完成,即等待线程终止。
  • yield(): 暂停当前正在执行的线程,并允许其他线程执行。
  • isAlive(): 判断线程是否还活着。
  • interrupt(): 中断线程,向线程发送一个中断信号,但并不一定终止线程的执行。
  • isInterrupted(): 判断线程是否被中断。
  • setName(String name): 设置线程的名称。
  • getName(): 获取线程的名称。
  • suspend(): 不推荐使用,暂停线程的执行。
  • resume(): 不推荐使用,恢复线程的执行。
  • setPriority(int priority): 设置线程的优先级,取值范围为1-10,默认为5。
  • getPriority(): 获取线程的优先级。
  • setDaemon(boolean on)设置为守护线程

我们再单独介绍一下几个常用并且不容易理解的成员方法:

1.setPriority(int priority)getPriority()

setPriority(int priority)方法用于设置线程的优先级,参数priority表示线程的优先级,取值范围为1-10,优先级默认为5。其中,1表示最低优先级,10表示最高优先级。

getPriority()方法用于获取线程的优先级,返回值为线程的优先级。

线程的优先级用于指定线程在竞争CPU资源时的优先级顺序。然而,优先级并不是绝对的执行顺序,仅作为建议给操作系统进行线程调度。

优先级的出现是因为我们JAVA中的线程在被CPU调度的时候,采用的是抢占式调度,也就是优先级越高,越容易抢到调度机会,而除了抢占式调度之外,我们还有非抢占调度,也就是CPU对线程轮流调度,不存在随机。

需要注意以下几点:

  1. 不同操作系统对线程优先级的处理可能有所不同。
  2. 线程的优先级不能保证一定按照预期执行,因为优先级可能受到操作系统调度算法的影响。
  3. 不应该过分依赖线程的优先级来实现业务逻辑,因为这可能导致代码的可移植性差。

一般来说,应用程序中使用默认优先级即可,除非有特殊需求。同时,应避免过于频繁地修改线程的优先级,以免导致优先级倾斜等问题。

2.setDaemon(boolean on)

setDaemon(boolean on)是Thread类提供的一个方法,用于设置线程的守护状态。当一个线程被设置为守护线程时,它会成为JVM中所有非守护线程的"服务员",在所有非守护线程结束后,JVM会自动退出,从而终止守护线程的执行。

具体来说,守护线程的特点如下:

  1. 守护线程通常用来提供后台服务或辅助功能,不影响程序的主要业务逻辑。
  2. 守护线程并不会影响JVM的正常终止,即使还有守护线程在执行,JVM也会自动退出。
  3. 当所有非守护线程结束后,守护线程会被自动终止,不会等待任务完成。

使用setDaemon(true)将线程设置为守护线程,使用setDaemon(false)将线程设置为用户线程(默认值)。

需要注意以下几点:

  1. setDaemon()方法只能在线程启动之前调用,一旦线程启动后,不能再修改守护状态。
  2. 守护线程不能持有任何可以独占资源的锁,因为它们可能会在任何时刻被终止,这样可能导致资源不正确释放或状态不一致的问题。
  3. 守护线程并不保证会执行完它们的任务,因此在编写守护线程时要特别小心,确保它们不会影响到程序的正确执行。

守护线程主要用于在后台提供服务或执行一些不断运行的任务,比如垃圾回收线程、定时任务线程等。一般情况下,我们在主线程中创建的线程都是用户线程,即非守护线程。

3.join()与yield()

join()与yield()都是用于线程的控制和协作的方法。

  1. join()

    • join()方法用于等待调用线程完成其执行,然后再继续执行当前线程。
    • 在一个线程A中调用另一个线程B的join()方法会使当前线程A阻塞,直到线程B执行完成。
    • 这通常用于多个线程之间的协作,确保某个线程在另一个线程执行完成后再继续执行。
    • 如果在join()方法中指定了超时时间,那么当前线程将等待指定的时间,如果超时仍未完成,则继续执行。
  2. yield()

    • yield()方法是线程的静态方法,它让出当前线程的执行权,将其暂停,以便其他具有相同或更高优先级的线程可以执行。
    • yield()的作用是提高线程的执行效率和响应性。
    • 当一个线程调用yield()方法后,它会从运行状态转变为就绪状态,让出CPU执行权,然后和其他具有相同或更高优先级的线程竞争CPU资源。
    • 注意,yield()方法并不能保证使得当前线程暂停执行,它只是提供一个提示给线程调度器,告知可以进行线程切换。

需要注意的是,join()方法可以用于线程的协作,而yield()方法用于线程的调度。join()方法会阻塞线程直到目标线程执行完成,而yield()方法会主动让出CPU执行权,使得其他线程有机会执行。

总结:

        本文我们介绍了使用线程的三种方法以及线程类中的常见成员方法,多线程是处理高并发问题的一个重要手段,因此我们一定要学好多线程。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

【从零开始学习JAVA | 第三十八篇】应用多线程,【从零开始学习JAVA】,学习,java,线程,多线程,高并发

 文章来源地址https://www.toymoban.com/news/detail-635399.html

到了这里,关于【从零开始学习JAVA | 第三十八篇】应用多线程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【从零开始学习JAVA | 第三十三篇】File类

    目录 前言: File类: 构造方法: 常见成员方法: 总结:         本文我们将为大家介绍JAVA中一个比较使用的类:File类,他为我们提供了存储数据的功能,使得程序的数据不至于在运行结束之后就丢失,是一个很好的类。         File类是Java标准库中用于操作文件和目录

    2024年02月15日
    浏览(57)
  • 【从零开始学习JAVA | 第三十一篇】异常体系介绍

            本文我们将为大家介绍一下异常的整个体系,而我们学习异常,不是为了敲代码的时候不出异常,而是为了能够熟练的处理异常,如何解决代码中的异常。  我们就以这张图作为线索来详细介绍一下Java中的异常: 在Java中, Exception(异常)是一种表示非致命错误或异

    2024年02月15日
    浏览(91)
  • 【从零开始学习JAVA | 第三十二篇】 异常(下)新手必学!

    目录 前言:  Exceptions(异常): 异常的两大作用: 异常的处理方式: 1.JVM默认处理  2.自己捕获异常 3.抛出处理 自定义异常: 异常的优点: 总结:         前文我们详细的为大家介绍了整个异常体系的框架,本篇我们将为大家介绍 Exceptions 异常,我们会讲解他的作用以及

    2024年02月15日
    浏览(69)
  • 【从零开始学习JAVA | 第三十五篇】IO流综合练习

    目录 前言: 1.拷贝文件(含子文件) 思路: 2.文件加密 思路: 3.修改文件中的数据: 思路: 总结:         在前面我们为大家介绍了FILE类和IO类。这篇文章我们来练习一些综合使用的例子以此来巩固我们自己的所学知识。 建立一个读文件的流来读取文件,一个写文件的流

    2024年02月14日
    浏览(52)
  • JavaScript从入门到精通系列第三十八篇:详解JavaScript中DOM的查询

    😉😉 学习交流群: ✅✅1:这是 孙哥suns 给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群: 583783824   📚📚  工作微信: BigTreeJava 拉你进微信群,免费领取! 🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

    2024年02月05日
    浏览(45)
  • 【从零开始学习JAVA | 第八篇】String类

    目录 前言: String类: 常见的认识误区: 创建String类:  注意点: 总结:         String类是Java中最常见的一个类,本篇将对Stirng类的各种功能进行详细的介绍,各位小伙伴如果感兴趣可以点击进来观看。 Java中的String类是一个非常常用的类, 它表示一串字符序列 。Java的字

    2024年02月10日
    浏览(54)
  • 【从零开始学习JAVA | 三十四篇】IO流

    目录 前言: IO流介绍: IO流的常见方法: 1.字节流类: 2.字符流类: 总结:                 IO流就是存入和读取数据的解决方案,并且他是一个知识点很多的章节,因此我们关于IO流的介绍会分为多篇来进行详解,而掌握好IO流可以大大提高我们的效率,简化我们的代码执

    2024年02月13日
    浏览(106)
  • 【从零开始学习JAVA | 三十九篇】深入多线程

    目录 前言:         ​1.线程的寿命周期​ 2.线程的安全问题 3.锁 同步代码块: 同步方法: 死锁: 4.生产者和消费者模式(等待唤醒机制) 总结:         当今软件开发领域中,多线程编程已成为一项至关重要的技能。然而,要编写出高效、可靠的多线程程序并不容

    2024年02月13日
    浏览(62)
  • 从零开始学习 Java:简单易懂的入门指南之异常(二十八)

    异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是: 异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。 在Java等面向对象的编程语言中,异常本身

    2024年02月08日
    浏览(75)
  • 从零开始学习 Java:简单易懂的入门指南之线程同步(三十五)

    1.1卖票【应用】 案例需求 某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票 实现步骤 定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private int tickets = 100; 在SellTicket类中重写run()方法实现卖票,代码步骤如下

    2024年02月08日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包