Chapter11多线程

本文介绍了Java中的多线程概念,包括进程与线程的区别,线程的状态转换,以及如何通过创建Thread子类来实现多线程。通过一个售票程序的示例展示了多线程在并发操作中的应用,强调了线程同步的重要性,同时也指出了直接调用run()方法并不会实现并发的问题。
摘要由CSDN通过智能技术生成

一、多线程基础

1.进程与线程

线程是进程内一个相对独立的、可调度的执行单元,又称为轻量级进程。和进程类似,线程也有运行、就绪、阻塞等状态。线程必须拥有父进程。系统没有为线程分配资源,它与进程中的其他线程共享该进程的共享资源。同一进程的不同线程共享相同的地址空间,它们可以访问相同的变量和对象,实现线程间的信息共享。线程间的通信简单而有效,上下文切换非常快。

进程相当于一个应用程序(以QQ为例),进程间不能通信(因为内存不共享),QQ中的每一个聊天窗口便是线程。

2.多线程的好处

多线程程序是指一个程序中包含多个执行流,它是实现并发机制的有效手段。从逻辑的观点看,多线程意味着一个程序的多个语句快同时执行,但不等于多次启动一个程序

引入多线程设计原因

  1. 某些应用具有内在的多控制流结构,这些控制流具有合作性质,需要共享内容。采用多线程易于对问题建模
  2. 在需要多控制流的应用中,多线程比多进程在速度上具有绝对优势。统计表明,线程的建立速度约比进程的建立速度快100倍
  3. 采用多线程可以提高处理机与设备之间的并行性
  4. 在多处理机的硬件环境中,多线程可并行执行,从而可提高资源利用率和进程推进速度。

3.run()和start()方法

  1. run()方法是新线程启动的前提,start()方法是新线程启动的标志
  2. 当调用start()时,会自动告诉jvm机,此时我们需要开辟新的栈空间
  3. 当开辟完新的栈空间后,start()方法会自动弹栈,在新栈中,run()方法压栈
  4. 如果我们直接调用新对象的run()方法,此时不会造成多线程并发,因为此时相当于代码由上至下的顺序执行
  5. run()方法在分支栈中等价于原栈空间的main

4.多线程的状态

1.新生状态

在创建Thread实例后,此Thread对象就处于新生状态,此时线程已被创建但还未开始执行。是一个空线程对象,还没有分配到系统资源

2.就绪状态(*)

为了得到实际的线程,为线程创建属于它的内存资源,需要使用start()方法启动线程,此时线程属于就绪状态,等待cpu分配执行时间(cpu时间片),自动调用自己的run()方法,开启运行状态

主线程会继续执行start()方法下面的语句,这时run()方法可能还在执行,从而实现了多任务操作

3.运行状态

如果线程不能在一个时间片中执行完毕,会被中断,由执行状态回到就绪状态,等待下一轮cpu分配执行时间

运行状态可以调用yield()方法主动放弃执行,转到就绪状态。仍然可能被再次调用

4.阻塞状态(*)

阻塞状态其实是睡眠、资源阻塞、等待三种状态的结合体,此时线程仍是活的,只是缺乏运行的条件。

引起阻塞状态的因素:

  1. 睡眠:线程调用sleep()方法睡眠一段时间
  2. 资源阻塞:线程在等待一种资源
  3. 等待:调用了wait()方法使线程挂起,直到线程得到notify()或notifyAll()消息

阻塞状态时,会让出cpu,让其他保持就绪状态的线程获得可能的执行时间(cpu时间片)

5.死亡状态

如果线程的run()方法执行完毕,线程正常结束;或者线程执行过程中抛出一个未捕获的异常或错误,线程异常结束。结束后,线程处于死亡状态

一旦线程死亡,就不能复生。如果死亡状态任然调用start()方法,会出现运行时异常IllegalThreadException

二、多线程引例

1.多线程步骤

构建Thread子类对象引发多线程的步骤如下:

  1. 构建Thread子类,重写其中的run()方法
  2. 创建线程对象
  3. 线程对象调用start()方法启动该线程

2.代码实现


public class ThreadDemo {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start(); // 此处如果直接调用myThread.run()方法,会直接进行程序的顺序执行,不											会构成多线程
        for (int i = 0; i < 10; i++) {
            System.out.println("main-->" + i);

        }
    }
}
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("myThread-->" + i);
        }
    }
}

/**
*上面的代码包含三个线程,
1.main线程
2.thread线程
3.GC线程(守护线程)
**/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amEvnow4-1686493036672)(…/blog示意图/微信图片_20230609180331.png)]

3.代码分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LOl6zMgH-1686493036673)(…/blog示意图/多线程jvm示意图.png)]

三、多线程应用

多线程最为关键的好处即利用不同的线程操作同一个内容

下面是一个售票的小程序,两个售票员一起售卖100张门票,利用多线程实现

package GoodsTrade.administrator;

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread myThread = new MyThread(100);
        myThread.start();
        int num = myThread.getNum();
        while(num > 0) {
            myThread.sale();
        }
    }
}
class MyThread extends Thread {
    private int num;
    public MyThread() {}
    public MyThread(int num) { //构造函数,方便在定义对象时传入售票的票数
        this.num = num;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        sale();
    }
    public void sale() {
        while(num > 0) {
            try {
                sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(currentThread().getName() +
                    "正在出售第 " + this.num + " 张票,剩余票数:" + --num);
            setNum(num);
        }
    }
}

					//运行结果
/*
Thread-0正在出售第 100 张票,剩余票数:99
main正在出售第 100 张票,剩余票数:98
main正在出售第 98 张票,剩余票数:97
Thread-0正在出售第 97 张票,剩余票数:96
Thread-0正在出售第 96 张票,剩余票数:95
main正在出售第 96 张票,剩余票数:94
main正在出售第 94 张票,剩余票数:93
Thread-0正在出售第 93 张票,剩余票数:92
main正在出售第 92 张票,剩余票数:91
Thread-0正在出售第 91 张票,剩余票数:90
main正在出售第 90 张票,剩余票数:89
Thread-0正在出售第 90 张票,剩余票数:88
main正在出售第 88 张票,剩余票数:87
Thread-0正在出售第 88 张票,剩余票数:86
main正在出售第 86 张票,剩余票数:85
Thread-0正在出售第 85 张票,剩余票数:84
Thread-0正在出售第 84 张票,剩余票数:83
main正在出售第 84 张票,剩余票数:83
main正在出售第 83 张票,剩余票数:82
Thread-0正在出售第 82 张票,剩余票数:81
main正在出售第 81 张票,剩余票数:80
Thread-0正在出售第 80 张票,剩余票数:79
Thread-0正在出售第 79 张票,剩余票数:78
main正在出售第 78 张票,剩余票数:77
main正在出售第 77 张票,剩余票数:76
Thread-0正在出售第 77 张票,剩余票数:75
Thread-0正在出售第 75 张票,剩余票数:74
main正在出售第 74 张票,剩余票数:73
Thread-0正在出售第 73 张票,剩余票数:72
main正在出售第 73 张票,剩余票数:72
Thread-0正在出售第 72 张票,剩余票数:70
main正在出售第 72 张票,剩余票数:71
main正在出售第 70 张票,剩余票数:69
Thread-0正在出售第 70 张票,剩余票数:69
Thread-0正在出售第 69 张票,剩余票数:68
main正在出售第 69 张票,剩余票数:68
main正在出售第 68 张票,剩余票数:66
Thread-0正在出售第 68 张票,剩余票数:67
Thread-0正在出售第 66 张票,剩余票数:65
main正在出售第 65 张票,剩余票数:64
main正在出售第 64 张票,剩余票数:63
Thread-0正在出售第 63 张票,剩余票数:62
main正在出售第 62 张票,剩余票数:61
Thread-0正在出售第 62 张票,剩余票数:61
Thread-0正在出售第 61 张票,剩余票数:60
main正在出售第 60 张票,剩余票数:59
Thread-0正在出售第 59 张票,剩余票数:58
main正在出售第 59 张票,剩余票数:57
main正在出售第 57 张票,剩余票数:56
Thread-0正在出售第 57 张票,剩余票数:55
Thread-0正在出售第 55 张票,剩余票数:54
main正在出售第 54 张票,剩余票数:53
Thread-0正在出售第 53 张票,剩余票数:52
main正在出售第 53 张票,剩余票数:52
Thread-0正在出售第 52 张票,剩余票数:51
main正在出售第 51 张票,剩余票数:50
Thread-0正在出售第 50 张票,剩余票数:49
main正在出售第 49 张票,剩余票数:48
Thread-0正在出售第 48 张票,剩余票数:47
main正在出售第 48 张票,剩余票数:47
main正在出售第 47 张票,剩余票数:46
Thread-0正在出售第 46 张票,剩余票数:45
main正在出售第 45 张票,剩余票数:44
Thread-0正在出售第 45 张票,剩余票数:44
main正在出售第 44 张票,剩余票数:43
Thread-0正在出售第 43 张票,剩余票数:42
main正在出售第 42 张票,剩余票数:41
Thread-0正在出售第 41 张票,剩余票数:40
main正在出售第 40 张票,剩余票数:39
Thread-0正在出售第 40 张票,剩余票数:39
Thread-0正在出售第 39 张票,剩余票数:38
main正在出售第 39 张票,剩余票数:38
main正在出售第 38 张票,剩余票数:37
Thread-0正在出售第 37 张票,剩余票数:36
main正在出售第 36 张票,剩余票数:34
Thread-0正在出售第 36 张票,剩余票数:35
main正在出售第 34 张票,剩余票数:33
Thread-0正在出售第 34 张票,剩余票数:33
Thread-0正在出售第 33 张票,剩余票数:32
main正在出售第 32 张票,剩余票数:31
Thread-0正在出售第 31 张票,剩余票数:30
main正在出售第 31 张票,剩余票数:30
main正在出售第 30 张票,剩余票数:29
Thread-0正在出售第 29 张票,剩余票数:28
Thread-0正在出售第 28 张票,剩余票数:27
main正在出售第 27 张票,剩余票数:26
main正在出售第 26 张票,剩余票数:25
Thread-0正在出售第 26 张票,剩余票数:24
Thread-0正在出售第 24 张票,剩余票数:23
main正在出售第 23 张票,剩余票数:22
Thread-0正在出售第 22 张票,剩余票数:21
main正在出售第 22 张票,剩余票数:20
Thread-0正在出售第 19 张票,剩余票数:18
main正在出售第 20 张票,剩余票数:19
main正在出售第 18 张票,剩余票数:17
Thread-0正在出售第 18 张票,剩余票数:17
main正在出售第 17 张票,剩余票数:16
Thread-0正在出售第 17 张票,剩余票数:16
Thread-0正在出售第 16 张票,剩余票数:15
main正在出售第 15 张票,剩余票数:14
Thread-0正在出售第 14 张票,剩余票数:13
main正在出售第 14 张票,剩余票数:13
main正在出售第 13 张票,剩余票数:12
Thread-0正在出售第 13 张票,剩余票数:11
main正在出售第 11 张票,剩余票数:10
Thread-0正在出售第 11 张票,剩余票数:9
main正在出售第 9 张票,剩余票数:8
Thread-0正在出售第 9 张票,剩余票数:8
main正在出售第 8 张票,剩余票数:7
Thread-0正在出售第 7 张票,剩余票数:6
main正在出售第 6 张票,剩余票数:5
Thread-0正在出售第 6 张票,剩余票数:4
main正在出售第 4 张票,剩余票数:3
Thread-0正在出售第 4 张票,剩余票数:2
Thread-0正在出售第 2 张票,剩余票数:1
main正在出售第 2 张票,剩余票数:0
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值