java多线程

什么是进程?什么是线程?
什么是进程?进程就是是系统进行资源分配和调度的基本单位,并且进程是一个动态的概念,这个概念包括了进程的创建、运行、销毁的过程。一个进程可以包括多个线程,线程是更小的单位,线程(thread)是操作系统能够进行运算调度的最小单位。比如我们运行一个java程序,就会产生一个java进程,main函数所在的是一个线程,也被称为主线程。

一个进程可以产生多个线程,多个线程共享进程的堆和方法区,但是每个线程都有自己的程序计数器,虚拟机栈和本地方法栈。所以系统在线程之间的切换就要方便的多,至少比进程方便。

Linux的进程和线程的 堆栈 总结:
进程栈是运行时决定的,跟编译无关。

进程栈大小是比较随机的,不是固定的,但是一定比线程栈大,并且不会超过线程栈的2倍。

线程栈的大小是固定的,默认是8M,可以使用ulinit -a 查看,可以使用ulimit -s 修改

默认情况下,每个线程的栈空间是在进程的堆空间中分配的,一般来说,每个线程都是有自己独立的栈空间,并且为了隔离,线程的栈空间之间会有隔离,隔离地区guardsize一般是4K一旦触碰到隔离地区guardsize,就会报错。

为什么程序计数器是私有的?
程序计数器主要有2个作用,第一个、主要通过字节码解释器来控制程序运行的顺序,依次读取指令,通过这个来控制是顺序执行还是循环还是判断等。第二个、在多线程的情况下,如果线程执行的之后切换回来,需要知道 上次执行到哪儿了,程序计数器就是可以提供这个信息。

一句话总结,程序计数器为了能够让线程知道自己现在执行到哪儿了,和正在执行什么逻辑。

虚拟机栈和本地方法栈为什么是私有的?
虚拟机栈:每个java程序执行的时候,都会有一个栈,保存引用的常量,本地方法,局部变量等,方法的开始执行到结束,对应一个栈帧在java虚拟机栈中入栈和出栈的过程。

本地方法栈:这个作用和虚拟机栈差不多,区别就是它主要是为了对应的是java程序需要使用到的native的方法的服务,在后续的Hotspot虚拟机中,二者就合二为一了

一句话总结,就是为了线程中的局部变量不被其他线程访问,所以必须私有。

一句话总结堆和方法区
首先,堆和方法区是所有线程共享的资源,然后堆是最大的一块资源,所有的对象都在堆中分配资源,方法区保存已经被加载的类信息,方法,常量,静态变量,即时编译器编译后的代码等等。

并发和并行的区别?
并发:同一时间段内,多个任务都在执行(同一时刻只有一个任务在执行,但是这些任务都在抢占cpu资源保证自己能够执行)

并行:同一时间内,多个任务同时执行(同一时刻,有多个任务在执行)

为什么需要使用多线程?
总体上:

说白了就是比较快,因为现在计算机的硬件性能上来了,多线程比单线程要快,因为线程之间切换的调度比进程之间的切换快得多。

现在的并发量越来越大,多线程高并发是应对目前互联网发展的一种手段。

底层:

对于cpu来说,如果是单核时代,(举个例子)cpu在执行计算的时候,io就是空的,执行io的时候,计算就是空的,如果是多线程,可以保证执行io的时候,计算也可以执行,可以保证cpu的使用效率更多

多核时代,如果还是单线程,那么同一时间只有一个核被使用,如果是多线程,就可以做到同一时刻有多个核被使用。

多线程可能带来的问题
内存泄露,上下文切换,死锁

线程的生命状态?
一定是6种生命状态的一种,分别是NEW RUNNNABLE BLOCKED WAITING TIME_WAITING TERMINATED

状态名 解释
NEW 初始的状态,这个时候线程刚刚被创建,但是还没有被调用,也就是没有使用start方法
RUNNABLE 运行状态,java概念中,准备就绪状态和运行中状态统称为runnable
BLOCKING 阻塞状态,也就是目前线程被阻塞,一般是被锁阻塞,等待锁释放
WAITING 等待状态,正在等待其他的线程做出一些动作才能结束等待,比如通知或者中断
TIME_WAITING 超时等待状态,不同于waiting状态的是,他可以在时间超时之后自动返回。
TERMINATED 终止状态,表示目前线程已经结束运行。
java中,各种状态一定是下面的状态转移图的情况

在这里插入图片描述

一些注意:

进入waiting状态的线程需要等待其他线程的通知才能结束wait状态,而time_waiting状态多了一个超时时间到自动返回的过程。

线程在进入同步代码块(synchronized代码块或者synchronized方法的时候),同时锁被其他线程掌控未释放的情况下,就会进入阻塞态,直到拿到锁开始执行run方法。

线程在执行完run方法之后就会进入终止状态。

什么是上下文切换?
简单的来说,就是上下文切换是一个概念,因为线程肯定大于cpu的核心数量,所以在每个时刻,cpu的一个核心只能被一个线程执行,在这种情况下,cpu就会使用时间片的方法,轮转分配给每个线程,让每个线程都能够得到执行的机会,这样的一个线程处理一半,然后把cpu时间片给其他线程用的过程就是一个上下文切换。这个过程的时候,线程会通过程序计数器保存自己目前的状态,然后再让时间片,这样下次获取到cpu的时候就可以继续上一次的执行继续执行,这样的上下文切换的过程一般耗费了cpu绝大多数的时间,linux最好的优点就是上下文切换的时间耗时非常的小。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GGUOHHUO

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

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

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

打赏作者

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

抵扣说明:

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

余额充值