进程和线程理论知识

1.进程线程

一个进程包含多个线程,线程之间共享进程的资源,进程去找操作系统(OS)去申请内存,进程把申请到的内存分派给线程来使用
线程是cpu调度的最小单位
CPU核心数和线程数的关系:1:2,四核对应8个逻辑处理器,意味着可以同时跑8个线程,但是为什么我们的pc没有运行八个逻辑处理器(线程)就卡死呢,就是因为CPU的时间片轮转机制
CPU时间片轮转机制

2.并行并发

并行

并行

并发:并发的概念一定要有时间单位时间单位内执行了多少任务

在这里插入图片描述

多线程的好处:充分利用CPU资源,加快响应用户所用的时间,可以使我们的代码模块化、异步化、简单化
注意:
1.必须考虑线程的安全性,
2.死锁:死锁产生的条件

  • 互斥条件:一个资源每次只能被一个进程使用。
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  • 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

3.资源以及锁的竞争会导致性能下降
4.线程不可能无穷无尽:OS限制:Linux下最多1000个,windows:2000,新线程:os会给他分派资源,分派栈空间1M。单纯new1000个线程 ,就要1G左右,还有文件描述符(句柄、指针、引用的指向),会消耗大量的资源

3.多线程的启动方式
在这里插入图片描述

Java中的程序天生就是多线程的,启动线程的方式:
类:Thread:对线程的抽象
接口:Runnable:对任务的抽象
结束:
stop()
interrupt():对线程进行中断,(并不是终止:强制性的),而是添加了一个中断标志位(用isInterruptd()来判断),打了个招呼,说你应该中断了,可以不用理会,不是强制性的。所以线程是协作式的不是抢占式的,而且在kotlin中直接将多线程的处理叫做协程(Coroutines )
isInterrupted():boolean:当前线程是否被中断
static方法interrupted():判定完之后会将中断标志位置为false

4.使用方法

Thread里面直接调用
Runnable里:

  public static class BarryLRunnable implements Runnable {

        @Override
        public void run() {
            //先获取当前正在执行的线程然后再调佣isInterrupted()
            while (!Thread.currentThread().isInterrupted()) {
                //TODO
            }
        }
    }

    public static void main(String[] args) throws InterruptedException{
        BarryLRunnable barryLRunnable = new BarryLRunnable();
        Runnable target;
        Thread barryThread = new Thread(barryLRunnable);
        barryThread.start();
        Thread.sleep(1000);
        barryThread.interrupt();//添加中断标志位
    }


应当注意的是当TODO部分有另外的线程要执行而中断当前线程时,捕获到异常之后会将标志位flag置为false

 public static class BarryLRunnable implements Runnable {

        @Override
        public void run() {
            //先获取当前正在执行的线程然后再调佣isInterrupted()
            while (!Thread.currentThread().isInterrupted()) {
                //TODO
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    //捕捉到异常之后会将interrupt标志位置为false,所以我们需要手动调用interrupt中断方法
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
        }
    }

5.run()和start()的区别

xxx.run()永远执行在主线程,xxx.start()才会执行xxx线程
yield():将线程从运行转到可运行状态,时间片到期,只会让出时间片,不会让出锁
join():获取执行权进入运行状态,将线程串行,需要排队,join进去的线程先执行,优先级高
优先级0-10,默认为5
守护线程setDeamon(true),守护线程随着所有用户线程主的结束而结束,守护线程中finally不一定起作用

在这里插入图片描述
6.同步锁、内置锁

    //用在同步块上
    public void incCount() {
        synchronized (obj) {
            count++;
        }
    }

    //用在方法上
    public synchronized void incCount2() {
        count++;
    }

对象锁、类锁

volatile

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值