并发编程:Java线程的本质

1. 创建一个线程类

  • 可以正常运行
    在这里插入图片描述

1.1 点击start方法

  • start方法内有一个start0方法,而且start0方法是一个native本地方法。是通过JNI调用的系统方法,这个start0方法对应的系统创建线程的方法是pthread_create。
    在这里插入图片描述

2. linux的线程控制原语

2.1 centos安装man手册

yum install -y man-pages

在这里插入图片描述

2.2 查看pthread_create函数定义

man pthread_create

在这里插入图片描述

  • 根据man配置的信息可以得出pthread_create会创建一个线程,这个函数是linux系统的函数,可以用C或者C++直接调用,这个函数在pthread.h, 这个函数有四个参数
  1. pthread_t *thread:指向线程id的指针(传出参数,调用之后会传出被创建线程的id)
  2. const pthread_attr_t*attr:线程属性(一般传NULL,保持默认属性)
  3. void *(*start_routine)(void *):线程的启动后的主体函数(需要你定义一个函数,然后传函数名即可)
  4. void *arg:主体函数的参数(没有可以传nulll)
  • start_routine类似于Thread的run方法,具体的方法实现,都在run方法里。

3. 线程本质

  • Java中的线程与操作系统有什么关系?
    Java中的线程是通过JNI调用操作系统pthread_create函数创建的线程,Java的线程模型与操作系统一一对应。

4. 线程模型

  • java的线程(Thread)应该叫做用户线程,对应到操作系统,还有另外一种线程叫作内核线程
  • 用户线程和内核线程之间存在3种对应关系
  1. 一对一模型(HotSpot)
    即一个用户线程对应一个内核线程,内核负责每个线程的调度
    优点:
    (比如JVM几乎把所有对线程的操作都交给了内核)实现线程模型的容器(jvm)简单,所以我们经常听到在java中使用线程一定要慎重就是这个原因;
    缺点:
    对用户线程的大部分操作都会映射到内核线程上,引起用户态和内核态的频繁切换;
    内核为每个线程都映射调度实体,如果系统出现大量线程,会对系统性能有影响;
  2. 多对一线程模型
    多个用户线程对应到同一个内核线程上,线程的创建、调度、同步的所有细节全部由进程的用户空间线程库来处理。
    优点:
    用户线程的很多操作对内核来说都是透明的,不需要用户态和内核态的频繁切换,使线程的创建、调度、同步等非常快;
    缺点:
    由于多个用户线程对应到同一个内核线程,如果其中一个用户线程阻塞,那么该其他用户线程也无法执行;
    内核并不知道用户态有哪些线程,无法像内核线程一样实现较完整的调度、优先级等;
  3. 多对多模型
    结合了多对一模型和一对一模型的特点,将多个用户线程映射到少数但不止一个内核线程上。

5. 线程的状态

  • 线程是用户态还是内核态
    需要看cpu的状态,ring0(内核态),ring1,ring2,ring3(用户态)

6. 上下文切换

  1. 进程内部发生系统调用(只保存进程的私有信息),进程从用户态切换到内核态;
  2. 进程与进程之间的切换(保存进程信息,用于切换还原后程序继续执行);
  3. 线程与线程之间的切换
    3.1 进程内部线程与线程之间的切换;
    3.2 线程与外部进程里的线程之间的切换。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值