【JAVA 多线程】

本文深入探讨了Java中的多线程概念,包括进程与线程的区别、线程的四种创建方式,如继承Thread类和实现Runnable接口,并展示了如何设置线程名字、中断线程以及使用join方法。同时,讲解了主线程与子线程以及线程优先级的概念,为理解和实践Java多线程提供了详尽的指导。
摘要由CSDN通过智能技术生成

多线程

进程

进程(Process)是操作系统分配资源的基本单位,一个进程拥有的资源有自己的堆、栈、虚存空间(页表)、文件描述符等信息。

  • 进程编号 PID:进程的身份标识。
  • 进程的状态:
  1. 新建状态
  2. 就绪状态
  3. 运行状态
  4. 阻塞状态
  5. 销毁状态
  • 执行优先级
  • 上下文:保存本次执行状态,以便下次继续执行,这个过程就是一个上下文。
  • 内存地址

线程

线程(Thread)是操作系统能够进行运算调度的基本单位。它包含在进程中,是进程中的实际运行单位。

线程是轻量级的进程,一个进程中包含了多个线程,因此多个线程间可以共享进程资源

进程和线程的区别

区别1:

从属关系不同:
进程是正在运行程序的实例,进程中包含了线程,而线程中不能包含进程。

区别2:

描述侧重点不同:
进程是操作系统分配资源的基本单位,而线程是操作系统调度的基本单位。

区别3:

共享资源不同:
多个进程间不能共享资源,每个进程有自己的堆、栈、虚存空间(页表)、文件描述符等信息,而线程可以共享进程资源文件(堆和方法区)。

区别4:

上下文切换速度不同:
线程上下文切换速度很快(上下文切换指的是从一个线程切换到另一个线程),而进程的上下文切换的速度比较慢。

区别5:

操纵者不同:
一般情况下进程的操纵者是操作系统,而线程的操纵者是编程人员。

线程四种创建方式

  1. 继承 Thread 类创建线程
  2. 实现 Runnable 接口创建线程
  3. 实现 Callable 接口,通过 FutureTask 包装器来创建 Thread 线程
  4. 线程池:使用ExcutorService、Callable、Future 实现有返回结果的线程

使用继承 Thread 类创建线程

单线程与多线程

单线程

public class Thread02 {
    private String name;
    public Thread02() {
    }
    public Thread02(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private void run(){
        for (int i = 0; i < 5; i++) {
            // 获取当前线程的名字
            System.out.println(this.name+"执行了第"+i+"次");
        }
    }
    public void start(){
        run();
    }
    public static void main(String[] args) {
        Thread02 thread01 = new Thread02("线程01");
        Thread02 thread02 = new Thread02("线程02");
        thread01.start();
        thread02.start();
    }
}

线程01执行结束后线程02开始执行输出

线程01执行了第0次
线程01执行了第1次
线程01执行了第2次
线程01执行了第3次
线程01执行了第4次
线程02执行了第0次
线程02执行了第1次
线程02执行了第2次
线程02执行了第3次
线程02执行了第4

多线程

public class Thread01 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            // 获取当前线程的名字
            System.out.println(this.currentThread().getName()+"执行了第"+i+"次");
        }
    }
    public static void main(String[] args) {
        Thread01 thread01 = new Thread01();
        Thread01 thread02 = new Thread01();
        thread01.setName("线程01");
        thread02.setName("线程02");
        thread01.start();
        thread02.start();
    }
}

线程01和线程02交替执行输出

线程02执行了第0次
线程02执行了第1次
线程01执行了第0次
线程01执行了第1次
线程01执行了第2次
线程01执行了第3次
线程01执行了第4次
线程02执行了第2次
线程02执行了第3次
线程02执行了第4

主线程与子线程

主线程

public class Thread03 {
    public static void main(String[] args) {
        // 获取当前线程的名字
        System.out.println(Thread.currentThread().getName());
    }
}

输出

main

子线程

public class Thread03 extends Thread{
    @Override
    public void run() {
        // 获取当前线程的名字
        System.out.println(this.currentThread().getName());
    }
    public static void main(String[] args) {
        Thread03 thread03 = new Thread03();
        thread03.start();
    }
}

输出

Thread-0

操作线程的名字

public class Thread04 extends Thread{
    @Override
    public void run() {
        System.out.println(this.currentThread().getName());
    }
    public static void main(String[] args) {
        Thread.currentThread().setName("线程01");
        System.out.println(Thread.currentThread().getName());
        Thread04 thread = new Thread04();
        thread.setName("线程02");
        thread.start();
    }
}

输出

线程01
线程02

线程中断

public class Thread05 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                if(i == 5){
                    // 线程中断
                    Thread.currentThread().interrupt();
                }
                Thread.sleep(500);
                System.out.println(this.currentThread().getName()+">>> "+i);
            } catch (InterruptedException e) {
                // throw new RuntimeException(e);
                return;
            }
        }
    }
    public static void main(String[] args) {
        Thread05 thread05 = new Thread05();
        thread05.start();
    }
}

输出

Thread-0>>> 0
Thread-0>>> 1
Thread-0>>> 2
Thread-0>>> 3
Thread-0>>> 4

守护线程中断

public class Thread08 extends Thread{
    @SneakyThrows
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(500);
            System.out.println(this.currentThread().getName()+"今年"+(i+1)+"岁");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread.currentThread().setName("Jack");
        Thread08 thread08 = new Thread08();
        thread08.setName("Rose");
        // 守护线程
        thread08.setDaemon(true);
        thread08.start();
        for (int i = 0; i < 10; i++) {
            if (i == 5){
                break;
            }
            Thread.sleep(500);
            System.out.println(Thread.currentThread().getName()+"今年"+(i+1)+"岁");
        }
    }
}

输出

Rose今年1Jack今年1Jack今年2Rose今年2Jack今年3Rose今年3Jack今年4Rose今年4Jack今年5Rose今年5

join把指定的线程加入到当前线程

public class Thread10 extends Thread{
    private int num;
    @Override
    public void run() {
        System.out.println(this.getName()+"疯狂计算中");
        for (int i = 0; i < 50; i++) {
            num += i;
        }
        System.out.println(this.getName()+"疯狂计算结束");
    }
    public int getNum(){
        return num;
    }
    public static void main(String[] args) throws InterruptedException {
        Thread.currentThread().setName("经理");
        Thread10 thread10 = new Thread10();
        thread10.setName("小丽");
        System.out.println(Thread.currentThread().getName()+"说"+thread10.getName()+"呀!帮我算一个报表");
        thread10.start();
        // 把指定的线程加入到当前线程
        thread10.join();
        System.out.println(thread10.getName()+"计算结果>>> "+thread10.getNum());
    }
}

输出

经理说小丽呀!帮我算一个报表
小丽疯狂计算中
小丽疯狂计算结束
小丽计算结果>>> 1225

线程优先级

public class Thread11 extends Thread{
    public static void main(String[] args) {
        Thread11 thread01 = new Thread11();
        Thread11 thread02 = new Thread11();
        thread01.setName("线程01");
        thread02.setName("线程02");
        // 获取当前线程优先级别
        System.out.println(thread01.getName()+">>> "+thread01.getPriority());
        System.out.println(thread02.getName()+">>> "+thread02.getPriority());
        // 设置优先级
        thread01.setPriority(MAX_PRIORITY);
        thread02.setPriority(MIN_PRIORITY);
        System.out.println(thread01.getName()+">>> "+thread01.getPriority());
        System.out.println(thread02.getName()+">>> "+thread02.getPriority());
    }
}

输出

线程01>>> 5
线程02>>> 5
线程01>>> 10
线程02>>> 1

实现 Runnable 接口创建线程

Runnable接口

public class Thread03{
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + ">>> " + i);
                }
            }
        };
        Thread thread01 = new Thread(runnable);
        Thread thread02 = new Thread(runnable);
        Thread thread03 = new Thread(runnable);
        thread01.start();
        thread02.start();
        thread03.start();
    }
}

输出

Thread-2>>> 0
Thread-2>>> 1
Thread-2>>> 2
Thread-2>>> 3
Thread-2>>> 4
Thread-1>>> 0
Thread-1>>> 1
Thread-1>>> 2
Thread-1>>> 3
Thread-1>>> 4
Thread-0>>> 0
Thread-0>>> 1
Thread-0>>> 2
Thread-0>>> 3
Thread-0>>> 4

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rita_zzf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值