多线程的概念

多线程

同时执行多个任务,例如一个人一边听歌,一边跳舞

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

定义一个MyThread类继承Thread类,重写里面的run方法

java 复制代码
package com.itxs.demo01;

/**
 * @Classname : MyThread
 * @Description : TODO 自定义线程继承Thread类
 * @Author : lin_refuel@qq.com
 */
public class MyThread extends Thread{
    @Override
    public void run() {
        //super.run();
        for (int i = 0; i < 20; i++) {
            System.out.println("i = " + i);
        }
    }
}

测试多线程类

java 复制代码
package com.itxs.demo01;

/**
 * @Classname : demo01
 * @Description : TODO 多线程的测试类
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) {
    // 线程对象创建
        MyThread my01 = new MyThread();
        MyThread my02 = new MyThread();
        MyThread my03 = new MyThread();
        MyThread my04 = new MyThread();
        //开启线程的方法start
        my01.start();
        my02.start();
        my03.start();
        my04.start();
    }
}

线程名字的获取和设置

自定义线程继承Thread类

java 复制代码
package com.itxs.demo02;

/**
 * @Classname : MyThread
 * @Description : TODO 自定义线程 - 继承Thread类
 * @Author : lin_refuel@qq.com
 */
public class MyThread extends Thread {
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            // this.getName获取类中自己的Name值
            System.out.println(this.getName() + " i =" + i);
        }
    }
}

测试线程

java 复制代码
package com.itxs.demo02;

/**
 * @Classname : demo01
 * @Description : TODO 多线程名字设置的方式
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) {
         //创建线程对象
        // 方式一:通过构造方法进行设置每个线程名字
        MyThread my01 = new MyThread("线程01");
        MyThread my02 = new MyThread("线程02");
        MyThread my03 = new MyThread("线程03");
        MyThread my04 = new MyThread();
        // 方式二:通过方法setName设置线程名字
//        my01.setName("线程01");
//        my02.setName("线程02");
//        my03.setName("线程03");
        my04.setName("线程04");
        //开启线程
        my01.start();
        my02.start();
        my03.start();
        my04.start();
    }
}

运行结果:

获取正在运行的线程对象

获取正在运行的线程

java 复制代码
Thread.currentThread()

通过上面的方法,获取到每个运行线程的名字

java 复制代码
package com.itxs.demo02;

/**
 * @Classname : MyThread
 * @Description : TODO 自定义线程(输出0-19) - 继承Thread类
 * @Author : lin_refuel@qq.com
 */
public class MyThread extends Thread {
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            // this.getName获取类中自己的Name值
            System.out.println(Thread.currentThread().getName() + " i =" + i);
        }
    }
}
java 复制代码
package com.itxs.demo02;

/**
 * @Classname : demo03
 * @Description : TODO 获取每个正在运行的线程的方法
 * @Author : lin_refuel@qq.com
 */
public class demo03 {
    public static void main(String[] args) {
          // 创建几个线程对象,设置每个线程的名字
        MyThread my01 = new MyThread("多线程01");
        MyThread my02 = new MyThread("多线程02");
        MyThread my03 = new MyThread("多线程03");
        MyThread my04 = new MyThread("多线程04");
        //开启线程
        my01.start();
        my02.start();
        my03.start();
        my04.start();
        // main 其实也是一个线程,但是却是主线程
        // 输出0-19
        //设置主线程名字的方法 Thread.currentThread是获取正在运行的线程
        //setName是设置名字
        Thread.currentThread().setName("主线程");
        for (int i = 0; i < 20; i++) {
            System.out.println( Thread.currentThread().getName()+"i = " + i);
        }
    }
}

线程调度

  • 两种线程调度模型

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

    • 抢占调度模型:优先让优先级高的线程使用 CPU,如果线程的欧优先级相同,那么随机选择一个,优先级高的线程获取的 CPU 占用时间会相对多一丢丢丢丢丢......

    Java 使用的是抢占式的调度模型

线程优先级设置

  • Thread 类中设置和获取线程优先级的方法

    • public final int getPriority():返回次线程的优先级

    • public final void setProiority(int newPriority):更改次线程的优先级

自定义的线程类-继承Thread类

java 复制代码
package com.itxs.demo02;

/**
 * @Classname : MyThread
 * @Description : TODO 自定义线程(输出0-19) - 继承Thread类
 * @Author : lin_refuel@qq.com
 */
public class MyThread extends Thread {
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            // this.getName获取类中自己的Name值
            System.out.println(Thread.currentThread().getName() + " i =" + i);
        }
    }
}

优先级测试

java 复制代码
package com.itxs.demo02;

/**
 * @Classname : demo02
 * @Description : TODO 线程调度测试
 * @Author : lin_refuel@qq.com
 */
public class demo02 {
    public static void main(String[] args) {
        // 创建线程对象
        MyThread mt01 = new MyThread("线程01");
        MyThread mt02 = new MyThread("线程02");
        MyThread mt03 = new MyThread("线程03");
        //修改线程的优先级
        mt01.setPriority(Thread.MIN_PRIORITY);//1
        mt02.setPriority(Thread.NORM_PRIORITY);//5
        mt03.setPriority(Thread.MAX_PRIORITY);//10
        // 线程的优先级输出
//        System.out.println(mt01.getPriority());
//        System.out.println(mt02.getPriority());
//        System.out.println(mt03.getPriority());
        //开启线程测试那个线程优先完成
        mt03.start();
        mt02.start();
        mt01.start();
    }
}

线程控制

方法名 说明
static void sleep(long ms) 使当前正在执行的线程停留指定的毫秒数
void join() 等待这个进程死亡
void setDaemon(boolean on) 将此线程标记为守护进程,当运行线程都是守护线程时,JVM 将退出

sleep方法

案例:华山论剑

自定义线程类

java 复制代码
package com.itxs.demo02;

/**
 * @Classname : MyThread
 * @Description : TODO 自定义一个线程 - 继承Thread类
 * @Author : lin_refuel@qq.com
 */
public class MyThread extends Thread{
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 1; i <=20 ; i++) {
            System.out.println(Thread.currentThread().getName() + "出了第"+i+"招");
            try {
                Thread.sleep(1000);//停留一秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

sleep测试类

java 复制代码
package com.itxs.demo02;

/**
 * @Classname : demo02
 * @Description : TODO 线程测试 - sleep
 * @Author : lin_refuel@qq.com
 */
public class demo02 {
    public static void main(String[] args) {
         //创建线程对象
        MyThread mt01 = new MyThread("黄固");
        MyThread mt02 = new MyThread("欧阳锋");
        MyThread mt03 = new MyThread("段智兴");
        MyThread mt04 = new MyThread("洪七公");
        //开启线程
        mt01.start();
        mt02.start();
        mt03.start();
        mt04.start();
    }
}

join方法

歌曲《天下》,原唱:张杰,翻唱:池瑶和高鱼

java 复制代码
package com.itxs.demo03;

/**
 * @Classname : MyThread
 * @Description : TODO
 * @Author : lin_refuel@qq.com
 */
public class MyThread extends Thread {
    public MyThread() {
        super();
    }

    public MyThread(String name) {
        super(name);
    }

    // 定义一个数组存放歌词
    String[] song = {"烽烟起寻爱似浪淘沙",
            "遇见她如春水映梨花",
            "挥剑断天涯",
            "相思轻放下"
    };

    @Override
    public void run() {
        for (int i = 0; i < song.length; i++) {
            System.out.println(Thread.currentThread().getName() + "正在唱:" + song[i]);
        }
    }
}

测试-张杰唱完后,两个翻唱继续唱

java 复制代码
package com.itxs.demo03;

/**
 * @Classname : demo01
 * @Description : TODO
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) throws InterruptedException {
        //创建线程
        MyThread mt01 = new MyThread("张杰");
        MyThread mt02 = new MyThread("池瑶");
        MyThread mt03 = new MyThread("高鱼");
        //开启线程
        mt01.start();
        mt01.join();//等待张杰唱完,mt01执行完后执行后面的线程
        mt02.start();
        mt03.start();
    }
}

setDaemon()

守护线程,总结就是当创建的线程对象设置为守护线程后,主线程里面的内容执行完后,所有开启的多线程都会停止执行
自定义的线程,执行20次循环

java 复制代码
package com.itxs.demo04;

/**
 * @Classname : MyThread
 * @Description : TODO - 自定义线程
 * @Author : lin_refuel@qq.com
 */
public class MyThread extends Thread{
    public MyThread() {
        super();
    }

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+"报数:"+i);
        }
    }
}

测试守护线程

java 复制代码
package com.itxs.demo04;

/**
 * @Classname : demo01
 * @Description : TODO
 * @Author : lin_refuel@qq.com
 */
public class demo01 {
    public static void main(String[] args) {
         //创建线程对象
        MyThread mt01 = new MyThread("1号");
        MyThread mt02 = new MyThread("2号");
        MyThread mt03 = new MyThread("3号");
        System.out.println("开始报数");
        //mt01,02,03设置为守护线程
        mt01.setDaemon(true);
        mt02.setDaemon(true);
        mt03.setDaemon(true);
        // 线程开启
        mt01.start();
        mt02.start();
        mt03.start();

        // 主线程执行三次循环
        for (int i = 0; i < 3; i++) {
            System.out.println("报数中");
        }
        System.out.println("停止报数");
    }
}

线程的生命周期

  • 新建:创建线程对象(通过 start() 进入下一个环节)

  • 就绪:有执行资格,没有执行权(抢占 CPU 的执行权)

  • 运行:有执行资格,有执行权(可能被其他线程抢走 CPU 的执行权,则回到就绪状态,若遇到阻塞式方法,则失去运行权和执行这个,等待,当阻塞方法调用结束之后,回到就绪状态)

  • 死亡:线程死亡,成为垃圾

相关推荐
爱敲键盘的猴子8 分钟前
深入理解 Java HashMap
java·hashmap
霸道流氓气质9 分钟前
Java开发者AI编程常用MCP、Skills、Rules全景汇总
java·开发语言·ai编程
天涯醉青楼21 分钟前
Spring Boot 接口返回 Bean 时字段名“变形”的深度剖析与解决方案
java
步行cgn38 分钟前
MyBatis 高级映射与延迟加载完全指南
java·tomcat·mybatis
thefool11226639 分钟前
从中序与后序遍历序列构造二叉树
java
吴声子夜歌1 小时前
Java面试题——JVM(二)
java·开发语言·jvm
CRMEB1 小时前
商城大促活动策划全流程:从定目标到复盘四阶段
java·开发语言·人工智能·ai·开源·php
denglinqings1 小时前
Java开发从入门到精通所有课程
java·开发语言
星空1 小时前
maven镜像
java·maven
chuan.bai2 小时前
Java RAG 实战附录:qwen3 与 bge-m3 模型切换指南
java·人工智能·算法