进程与线程详解

本文详细介绍了进程和线程的概念,包括进程的创建、线程的管理和区别,以及多线程创建、线程安全问题、synchronized和volatile关键字的使用。还深入探讨了线程的等待集、单例模式、阻塞式队列、定时器和线程池等多线程编程中的关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、进程 

二、线程

三、进程和线程的区别

四、多线程的创建和常见方法

1、多线程的创建

2、多线程的常用方法

五、线程的安全问题

5.1、线程不安全的原因是什么?

5.2如何解决线程不安全问题

六、锁--synchronized 关键字

七、volatile 关键字的作用和用法

synchronized和volatile的区别

八、对象的等待集

8.1、wait方法

8.2、notify方法

九、多线程案例

9.1、单例模式

9.2、阻塞式队列

9.3、定时器

9.4、线程池


一、进程 

进程是操作系统中一种非常重要的软件资源,当我们把一个可执行程序exe运行起来的时候,系统就会随之创建一个进程,如果这个程序结束系统会随之销毁对应的进程。

当运行exe文件时,exe文件中的很多内容都加载到内存中,通过分配资源来执行这个程序包含的指令的过程叫做进程

进程的管理是通过先描述在组织的方法:

在Linux中每创建一个进程就会创建一个PCB这样的类的实例

创建一个进程,本质上就是在内核中先创建一个PCB对象,然后将这个对象加入到链表中。

结束一个进程的时候,本质上就是在内核中找到这个PCB对象,将他从链表中删除,并且释放该对象。

我们通过任务管理器中看到的所以的进程信息就是在内核中遍历该链表,依次读取PCB中的信息。

 PCB中包含的信息:

1、进程id----进程的身份标识。

2、一组内存指针----指向该进程持有的一些重要数据在内存中的位置。 

以及状态、优先级、进程的记账信息、上下文,这些模块交做调度器来实现进程模块的调度,

为了让这么多进程可以在有限的CPU上并发执行。

状态:判断是在运行还是在休眠等······

优先级:判断这个进程是优先在CPU上执行还是放到后面······

进程的记账信息:记录进程在CPU上执行的时间,通过时间来限制一段进程的执行······

上下文:保存进程在CPU上执行的进度,方便下次继续执行······

二、线程

所谓的线程其实是一种轻量级的进程

1、一个进程中包含多个线程

2、相比于进程成本更低,大部分资源是和原来的线程共享的,主要共享内存资源和打开的文件,上下文等是不能共享的。

3、每个线程都有一段自己的执行逻辑,每个线程都是一个独立的执行流。

注意:当创建出一个进程时,会随之创建一个主线程。

线程中的管理模式和进程中的一样都是先描述在组织。

一个线程和一个PCB对应,一个进程可能和多个PCB对应,在PCB中会有线程组id来对应一组线程。

进程中最多可以有多少个线程取决于:

1、CPU的个数。

2、和线程执行的任务类型也相关(CPU密集性和IO密集性)。

三、进程和线程的区别

根本区别:进程是操作系统分配资源的最小单位,线程是任务调动和执行的最小单位。

在开销方面:每个进程都有独立的代码和数据空间,程序切换会有较大的开销。线程之间共享代码和数据,每个线程都有自己独立的栈和调度器,线程之间的切换的开销较小。

所处环境:一个操作系统中可以运行多个进程,一个进程中有多个线程同时执行。

内存分配方面:系统在运行时会为每个进程分配内存,系统不会单独为每个线程分配内存。

包含关系:创建进程时系统会自动创建一个主线程由主线程完成,进程中有多线程时,由多线程共同执行完成。

四、多线程的创建和常见方法

1、多线程的创建

1、通过创建类继承Thread来调用

    //1、通过类直接创建
    static class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("qewrwerwerw");
        }
    }

    public static void main(String[] args) {
        Thread t=new MyThread();
        t.start();
    }

2、通过Thread匿名内部类进行调用

    public static void main(String[] args) {
        Thread t=new Thread(){
            @Override
            public void run() {
                System.out.println("wefwefwef");
            }
        };
        t.start();
    }

3、通过创建类实现Runnable接口实现

    static class MyThread implements Runnable{
        @Override
        public void run() {
            System.out.println("awetqeragearga");
        }
    }

    public static void main(String[] args) {
        Thread t=new Thread(new MyThread());
        t.start();
    }

4、通过Runnable实现匿名内部类调用实现

    public static void main(String[] args) {
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                System.out.println("w3rqetqwetqw");
            }
        };
        Thread r=new Thread(runnable);
        r.start();
    }

5、通过lambad表达式调用

    public static void main(String[] args) {
        Thread t=new Thread(()->System.out.println("asdasfasfasfas"));
        t.start();
    }

2、多线程的常用方法

2.1、多线程的构造方法

方法 解释
Thread() 创建线程对象
Thread(Runnable target) 使用Runnable类型创建对象
Thread(String name) 创建线程对象并命名
Thread(Runnable target,String name) 使用Runnable类型创建对象并命名

例:

    public static void main(String[] args) {
        Thread t=new Thread("我是你爸爸"){
            @Override
            public void run() {
                System.out.println("你好");
                while (true){
                    
                }
            }
        };
        t.start();
        while(true){
            
        }
    }

 2.2、线程的常见属性

属性 获取方法
ID getId()
名称 getName()
状态 getState()
优先级 getPriority()
是否后台线程 isDaemon()
是否存活 isAlive()
是否被中断 isInterrupted()

2.3、中断程序

1)让线程run执行(比较温和)

    private static boolean cread=false;

    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(){
            @Override
            public void run() {
                while(!cread){
                    System.out.println("转账中");
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t.start();

        Thread.sleep(2000);
        System.out.println("有内鬼终止交易");
        cread=true;
    }

2)调用线程的interrupt方法来(比较激烈)

    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(){
            @Override
            public void run() {
                while(!Thread.currentThread().isInterrupted()){
                    System.out.println("转账中");
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        //break;
                    }
                }
                System.out.println("转账被终止");
            }
        };

        t.start();
        Thread.sleep(2000);
        System.out.println("有内鬼终止交易");
        t.interrupt();
    }

Thread.interrupted()判断当前线程中断标志被设置--清除中断

Thread.currentThread().isInterrupted()判断指定线程的中断标志--不清除中断标志

2.4、线程的等待和休眠

线程之间是并发执行的

线程的等待:

我们可以通过join方法来阻塞线程,join为了控制线程结束的先后顺序。

    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(){
            @Override
            public void run() {
                for(int i=0;i<3;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("我在执行t1");
                }
            }
        };

        Thread t2=new Thread(){
            @Override
            public void run() {
                for(int i=0;i<3;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("我在执行t2");
                }
            }
        };

        t2.start();
        t1.start();
        t2.join();
        t1.join();
    }

当两个线程执行完成之后,主线程才会继续向下执行,我们可以通过这种方法来获取时间。

线程的休眠 :

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

now just do it

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

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

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

打赏作者

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

抵扣说明:

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

余额充值