• Java学习笔记(二十八)


    在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第二十八篇博客。

    本篇博客介绍了Java的多线程初级内容。

    本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11

    目录

    多线程初级

    进程与线程

    继承Thread类的方式实现多线程

    设置和获取线程名称

    线程优先级

    线程控制

    线程生命周期

    实现Runnable接口的方式实现多线程


    多线程初级

    进程与线程

    进程是正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有自己的内存空间和系统资源。

    线程是进程中的单个顺序控制流,是一条执行路径。一个进程如果只有一条执行路径,就是单线程。一个进程如果有多条执行路径,就是多线程。

    继承Thread类的方式实现多线程

    要通过继承Thread类的方式实现多线程,要先定义一个类继承Thread类,然后在这个类中重写run方法,再创建此类对象,最后启动线程。

    run方法封装被线程执行的代码,直接调用run方法相当于普通方法调用。

    start方法启动线程,然后会由JVM调用此线程的run方法。

    1. public class MyThread extends Thread{
    2. public void run(){
    3. int i;
    4. for(i = 1; i <= 100; i += 1) {
    5. System.out.println(i);
    6. }
    7. }
    8. }

    MyThread类继承了Thread类,重写run方法,run方法输出1至100。

    1. public class MyThreadtest1 {
    2. public static void main(String[] args) {
    3. MyThread my1 = new MyThread();
    4. MyThread my2 = new MyThread();
    5. my1.start();
    6. my2.start();
    7. }
    8. }

    程序创建了两个MyThread类对象,然后调用start方法。

    程序实现了多线程,由于输出过长,此处不再展示。

    设置和获取线程名称

    void setName(String name)将此线程的名称改为参数name。

    String getName()返回此线程名称。

    通过构造方法也可以设置线程名称。

    public static Thread currentThread()返回当前正在执行的线程对象的引用。

    1. public class MyThread extends Thread{
    2. public void run(){
    3. int i;
    4. for(i = 1; i <= 100; i += 1) {
    5. System.out.println(getName() + " " + i);
    6. }
    7. }
    8. }

    MyThread类继承了Thread类,重写run方法,run方法输出1至100,每次都会输出线程名称。

    1. public class MyThreadtest2 {
    2. public static void main(String[] args){
    3. System.out.println(Thread.currentThread());
    4. MyThread my1 = new MyThread();
    5. MyThread my2 = new MyThread();
    6. my1.setName("A");
    7. my2.setName("B");
    8. my1.start();
    9. my2.start();
    10. }
    11. }

    程序首先输出当前线程名称,然后创建了两个MyThread类对象并调用start方法。

    下面是程序开始的一部分输出:

    Thread[main,5,main]
    B 1
    A 1
    B 2
    A 2
    B 3
    A 3
    B 4
    A 4
    B 5
    A 5

    线程优先级

    线程有两种调度模型。

    分时调度模型所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片。

    抢占式调度模型优先让优先级高的线程使用CPU,如果线程优先级相同会随机选择一个,优先级高的线程获取的CPU的时间片相对多一些。

    Java使用抢占式调度模型。

    如果计算机只有一个CPU,那么CPU在某个时刻只能执行一条指令。线程只有得到CPU时间片才能执行指令。多线程执行有随机性,因为谁抢到CPU的使用权是不一定的。

    public final int getPriority()返回此线程优先级。

    public final void setPriority(int newPriority)更改此线程优先级。

    线程默认优先级是5,优先级的范围是1至10。

    线程优先级高仅仅表示线程获取CPU时间片的几率高。

    1. public class MyThreadtest3 {
    2. public static void main(String[] args){
    3. MyThread my1 = new MyThread();
    4. MyThread my2 = new MyThread();
    5. MyThread my3 = new MyThread();
    6. my1.setName("A");
    7. my2.setName("B");
    8. my3.setName("C");
    9. my1.setPriority(6);
    10. my2.setPriority(7);
    11. my3.setPriority(8);
    12. my1.start();
    13. my2.start();
    14. my3.start();
    15. }
    16. }

    MyThread类见上文。程序创建了三个MyThread类对象,然后设置姓名和优先权,随后启动多线程。

    下面是程序一次输出的一部分:

    C 1
    B 1
    A 1
    B 2
    C 2
    B 3
    A 2
    B 4
    C 3
    B 5
    A 3
    B 6
    C 4
    B 7
    A 4
    B 8


    线程控制

    static void sleep(long millis)让当前执行的线程暂停执行millis毫秒。

    void join()表示这个线程结束后再执行其他线程。

    void setDaemon(boolean on)将此线程记为守护线程,如果运行的线程都是守护线程,那么程序结束。

    线程生命周期

    首先创建一个线程对象,然后用start方法启动,此时有执行资格无执行权,如果抢到CPU执行权就运行,如果运行时其他线程抢走CPU执行权就失去执行权,等待抢到CPU执行权。如果用sleep或其他阻塞方法就失去执行资格和执行权,等待sleep方法时间到或者阻塞方式结束,随后获得执行资格,等待抢到CPU控制权。线程执行完毕后就变成垃圾。

    实现Runnable接口的方式实现多线程

    通过实现Runnable接口的方式实现多线程,需要定义一个类实现Runnable接口,随后在这个类中重写run方法,然后创建这个类的对象。再创建一个Thread类对象,把这个类的对象作为构造方法的参数,再启动线程。

    多线程可以通过继承Thread类或实现Runnable接口的方式实现。实现Runnable接口避免Java单继承的局限性,适合多个相同程序的代码处理同一个资源的情况,把线程和程序的代码和数据有效分离。

    1. public class MyRunnable implements Runnable{
    2. public void run(){
    3. int i;
    4. for(i = 1; i <= 100;i += 1){
    5. System.out.println(Thread.currentThread() + " " + i);
    6. }
    7. }
    8. }

    MyRunnable类实现了Runnable接口,重写了run方法。

    1. public class MyRunnabletest {
    2. public static void main(String[] args){
    3. MyRunnable mr = new MyRunnable();
    4. Thread t1 = new Thread(mr);
    5. Thread t2 = new Thread(mr);
    6. t1.start();
    7. t2.start();
    8. }
    9. }

    程序创建了一个MyRunnable类对象mr,随后通过Thread创建了两个对象,构造方法参数为mr。然后启动多线程。

    程序的输出是(只展示前十五行结果):

    Thread[Thread-1,5,main]  1
    Thread[Thread-1,5,main]  2
    Thread[Thread-0,5,main]  1
    Thread[Thread-1,5,main]  3
    Thread[Thread-0,5,main]  2
    Thread[Thread-1,5,main]  4
    Thread[Thread-0,5,main]  3
    Thread[Thread-1,5,main]  5
    Thread[Thread-0,5,main]  4
    Thread[Thread-1,5,main]  6
    Thread[Thread-0,5,main]  5
    Thread[Thread-1,5,main]  7
    Thread[Thread-0,5,main]  6
    Thread[Thread-1,5,main]  8
    Thread[Thread-0,5,main]  7

     

  • 相关阅读:
    unity面试八股文 - 框架设计与资源管理
    合肥先进光源束测系统工控机数量需求的初步估计
    gptp报文完成时间同步原理
    JavaScript数据类型有哪些?
    Redis学习笔记:Jedis
    大数据技术之-Hive源码
    SpringMVC学习笔记
    51单片机STC89C52RC——3.1 数码管静态展示
    基于战争优化算法(WSO)的光伏模型参数估计研究(Matlab代码实现)
    系统工程利用计算机作为工具
  • 原文地址:https://blog.csdn.net/m0_71007572/article/details/126431286