• Java-多线程


    勤能补拙
    文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

    在这里插入图片描述


    前言

    如果一次只完成一件事情,会很容易实现,但现实生活中很多事情都是同时进行的,所以在Java中为了模拟这种状态,引入了线程机制。简单地说,当程序同时完成多件事情时,就是所谓的多线程程序。多线程应用相当广泛,使用多线程可以创建窗口程序、网络程序等。本章将由浅入深地介绍多线程。

    一、线程简介

    世间万物都可以同时完成很多工作,例如,人体可以同时进行呼吸、血液循环、思考问题等活动,用户既可以使用计算机听歌,也可以使用它打印文件,而这些活动完全可以同时进行,这种思想放在Java中被称为并发,而将并发完成的每一件事情称为线程。

    二、实现线程的两种方式

    在Java中主要提供两种方式实现线程,分别为继承java.lang.Thread类与实现java.lang.Runnable接口。

    1、继承Thread类

    Thread类是java.lang包中的一个类,从这个类中实例化的对象代表线程,程序员启动一个新线程需要建立Thread实例。Thread类中常用的两个构造方法如下:

    public Thread():创建一个新的线程对象。
    public Thread(String threadName):创建一个名称为threadName的线程对象。
    
    • 1
    • 2

    继承Thread类创建一个新的线程的语法如下:

    public class ThreadTest extends Thread{
    }
    
    • 1
    • 2

    完成线程真正功能的代码放在类的run()方法中,当一个类继承Thread类后,就可以在该类中覆盖run()方法,将实现该线程功能的代码写入run()方法中,然后同时调用Thread类中的start()方法执行线程,也就是调用run()方法。
    Thread对象需要一个任务来执行,任务是指线程在启动时执行的工作,该工作的功能代码被写在run()方法中。run()方法必须使用以下语法格式:

    public void run(){
    }
    
    • 1
    • 2

    2、实现Runnable接口

    到目前为止,线程都是通过扩展Thread类来创建的,如果程序员需要继承其他类(非Thread类),而且还要使当前类实现多线程,那么可以通过Runnable接口来实现。例如,一个扩展JFrame类的GUI程序不可能再继承Thread类,因为Java语言中不支持多继承,这时该类就需要实现Runnable接口使其具有使用线程的功能。
    实现Runnable接口的语法如下:

    public class Thread extends Object implements Runnable
    
    • 1

    实现Runnable接口的程序会创建一个Thread对象,并将Runnable对象与Thread对象相关联。Thread类中有以下两个构造方法:

    public Thread(Runnable target)
    public Thread(Runnable target,String name)
    
    • 1
    • 2

    这两个构造方法的参数中都存在Runnable实例,使用以上构造方法就可以将Runnable实例与Thread实例相关联。
    使用Runnable接口启动新的线程的步骤如下:
    1、建立Runnable对象。
    2、使用参数为Runnable对象的构造方法创建Thread实例。
    3、调用start()方法启动线程。

    三、线程的生命周期

    线程具有生命周期,其中包含7种状态,分别为出生状态、就绪状态、运行状态、等待状态、休眠状态、阻塞状态和死亡状态。出生状态就是线程被创建时处于的状态,在用户使用该线程实例调用start()方法之前线程都处于出生状态:当用户调用start()方法后,线程处于就绪状态(又被称为可执行状态);当线程得到系统资源后就进入运行状态。
    一旦线程进入可执行转态,它会在就绪与运行状态下转换,同时也有可能进入等待、休眠、阻塞或死亡状态。当处于运行状态下的线程调用Thread类中wait()方法时,该线程便进入等待状态,进入等待状态的线程必须调用Thread类中的notify()方法才能被唤醒,而notifyAll()方法是将所有处于等待状态下的线程唤醒;当线程调用Thread类中的sleep()方法时,则会进入休眠状态。如果一个线程在运行状态下发出输入/输出请求,该线程将进入阻塞状态,在其等待输入/输出结束时线程进入就绪状态,对于阻塞的线程来说,即使系统资源空闲,线程依然不能回到运行状态。当线程的run()方法执行完毕时,线程进入死亡状态。

    四、操作线程的方法

    操作线程有很多方法,这些方法可以使线程从某一种状态过渡到另一种状态。

    1、线程的休眠

    一种能控制线程行为的方法是调用sleep()方法,sleep()方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位。
    sleep()方法的语法如下:

    try{
    	Thread.sleep(2000);
    }catch(InterruptedException e){
    	e.printStackTrace();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    上述代码会使线程在2秒之内不会进入就绪状态。由于sleep()方法的执行有可能抛出InterruptedException异常,所以将sleep()方法的调用放在try-catch块中。虽然使用了sleep()方法的线程在一段时间内会醒来,但是并不能保证它醒来后进入运行状态,只能保证它进入就绪状态。

    2、线程的加入

    如果当前某程序为多线程程序,假如存在一个线程A,现在需要插入线程B,并要求线程B先执行完毕,然后再继续执行线程A,此时可以使用Thread类中的join()方法来完成。这就好比此时读者正在看电视,突然有人上门收水费,读者必须付完水费后才能继续看电视。
    当某个线程使用join()方法加入到另外一个线程时,另一个线程会等待该线程执行完毕后再继续执行。

    3、线程的中断

    以往有的时候会使用stop()方法停止线程,但当前版本的JDK早已废除了stop()方法,不建议使用stop()方法来停止一个线程的运行。现在提倡在run()方法中使用无限循环的形式,然后使用一个布尔型标记控制循环的停止。

    4、线程的礼让

    Thread类中提供了一种礼让方法,使用yield()方法表示,它只是给当前正处于运行状态的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。
    yield()方法使具有同样优先级的线程有进入可执行状态的机会,当当前线程放弃执行权时会再度回到就绪状态。对于支持多任务的操作系统来说,不需要调用yield()方法,因为操作系统会为线程自动分配CPU时间片来执行。

    五、线程的优先级

    每个线程都具有各自的优先级,线程的优先级可以表明在程序中该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态。但这并不意味着低优先级的线程得不到运行,而只是它运行的几率比较小,如垃圾回收线程的优先级就较低。

    六、线程同步

    在单线程程序中,每次

    七、总结

    这里的相关内容还没有整理完毕,文章后面持续更新,建议收藏。

    文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。

    可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。

  • 相关阅读:
    思腾云计算
    Ubuntu1804 安装后无法使用root登录解决方法
    C语言之动态内存分配二
    IT行业的革新力量:技术进步与未来展望
    Css3 2D转换 2D转换之移动tranlate
    Apache DolphinScheduler新一代分布式工作流任务调度平台实战-中
    java毕业生设计研究生推免系统计算机源码+系统+mysql+调试部署+lw
    基于Python的Flask框架实现的寻宝通关游戏 课程论文+项目源码
    LongAdder原理浅析
    postman和node.js的使用、YApi 新版如何查看 http 请求数据
  • 原文地址:https://blog.csdn.net/weixin_44096133/article/details/126148066