精华内容
下载资源
问答
  • 为什么有锁会引起上下文切换

    千次阅读 2019-07-13 15:09:15
    锁竞争、上下文切换、线程迁移的监控 程序的多线程应用,必然会出现锁的竞争。锁竞争一次消耗的高达80,000个(甚至更高)时钟周期,那么锁的竞争过多必然会导致性能瓶颈 既然如此消耗性能,又该如何去监测锁竞争呢? 第...

    锁竞争、上下文切换、线程迁移的监控
    程序的多线程应用,必然会出现锁的竞争。锁竞争一次消耗的高达80,000个(甚至更高)时钟周期,那么锁的竞争过多必然会导致性能瓶颈

    既然如此消耗性能,又该如何去监测锁竞争呢?

    第一步:竞争的监测

    第二步:若出现锁的竞争,就需要利用线程转储(thread dump)去分析锁竞争严重的原因了

    解释如下:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • Java多线程的上下文切换

    千次阅读 2017-05-13 18:26:18
    对于上下文切换不同的操作系统模式也不尽相同,这里我们只讨论Unix系统,在我之前的文章中提到过windows的抢占式,这里就不在赘述。 无论是单核还是多核CPU都是支持多线程代码的,CPU通过给每个线程分配CPU时间片来...

    对于上下文切换不同的操作系统模式也不尽相同,这里我们只讨论Unix系统,在我之前的文章中提到过windows的抢占式,这里就不在赘述。
    无论是单核还是多核CPU都是支持多线程代码的,CPU通过给每个线程分配CPU时间片来实这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程是同时执行的,时间片一般是几十毫秒(ms)
    CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。 很明显上下文切换会影响多线程的执行速度。

    如何减少上线文切换

    减少上下文切换的方法有
    1、无锁并发编程。
    多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一
    些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。
    2、CAS算法。
    Java的Atomic包使用CAS(compare and swap)算法来更新数据,而不需要加锁。
    3、使用最少线程。避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这
    样会造成大量线程都处于等待状态。
    4、协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

    减少上下文切换的例子

    下面我们看一个通过减少线上大量WAITING的线程,来减少上下文切换次数的例子:
    使用jstack命令dump线程信息,看看pid为3117的进程里的线程都在做什么

    sudo -u admin /opt/java/bin/jstack 31177 > /home/java/dump17

    统计所有线程分别处于什么状态,发现300多个线程处于WAITING(onobjectmonitor)状态

    grep java.lang.Thread.State dump17 | awk '{print $2$3$4$5}'
    | sort | uniq -c
    39 RUNNABLE
    21 TIMED_WAITING(onobjectmonitor)
    6 TIMED_WAITING(parking)
    51 TIMED_WAITING(sleeping)
    305 WAITING(onobjectmonitor)
    3 WAITING(parking)

    打开dump文件查看处于WAITING(onobjectmonitor)的线程在做什么。发现这些线程基本全是JBOSS的工作线程,在await。说明JBOSS线程池里线程接收到的任务太少,大量线程都闲着。

    "http-0.0.0.0-7001-97" daemon prio=10 tid=0x000000004f6a8000 nid=0x555e in
    Object.wait() [0x0000000052423000]
    java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpoint$Worker)
    at java.lang.Object.wait(Object.java:485)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.await(AprEndpoint.java:1464)
    - locked <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpoint$Worker)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1489)
    at java.lang.Thread.run(Thread.java:662)

    减少JBOSS的工作线程数,找到JBOSS的线程池配置信息,将maxThreads降到100

    <maxThreads="250" maxHttpHeaderSize="8192"
    emptySessionPath="false" minSpareThreads="40" maxSpareThreads="75"
    maxPostSize="512000" protocol="HTTP/1.1"
    enableLookups="false" redirectPort="8443" acceptCount="200" bufferSize="16384"
    connectionTimeout="15000" disableUploadTimeout="false" useBodyEncodingForURI= "true">

    重启JBOSS,再dump线程信息,然后统计WAITING(onobjectmonitor)的线程,发现减少了175个。WAITING的线程少了,系统上下文切换的次数就会少,因为每一次从WAITTING到RUNNABLE都会进行一次上下文的切换。读者也可以使用vmstat命令测试一下。

    grep java.lang.Thread.State dump17 | awk '{print $2$3$4$5}'
    | sort | uniq -c
    44 RUNNABLE
    22 TIMED_WAITING(onobjectmonitor)
    9 TIMED_WAITING(parking)
    36 TIMED_WAITING(sleeping)
    130 WAITING(onobjectmonitor)
    1 WAITING(parking)

    为什么要减少上下文切换

    当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为“上下文切换”(“context switch”)。CPU会在一个上下文中执行一个线程,然后切换到另外一个上下文中执行另外一个线程。上下文切换并不廉价,是比较耗时的

    展开全文
  • 引起上下文切换的原因引起上下文切换的原因如下 引起上下文切换的原因如下 当前正在执行的任务完成,系统的cpu正常调度下一个任务 当前正在执行的任务遇到i/o等阻塞操作,调度器挂起此任务,继续调度下一个任务。 ...

    引起上下文切换的原因

    引起上下文切换的原因如下

    • 当前正在执行的任务完成,系统的cpu正常调度下一个任务
    • 当前正在执行的任务遇到i/o等阻塞操作,调度器挂起此任务,继续调度下一个任务。
    • 多个任务并发抢占资源,当前任务么有抢到锁资源,被调度器挂起,继续调度下一个任务,
    • 用户的代码挂起当前任务,比如线程执行sleep方法,让出CPU。
    • 硬件中断。
    展开全文
  • 什么是上下文切换 即使是单核CPU也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程...

    来自方腾飞老师《Java并发编程的艺术》第一章

    什么是上下文切换

           即使是单核CPU也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程时同时执行的,时间片一般是几十毫秒(ms)。

           CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再次加载这个任务的状态,从任务保存到再加载的过程就是一次上下文切换

           这就像我们同时读两本书,当我们在读一本英文的技术书籍时,发现某个单词不认识, 于是便打开中英文词典,但是在放下英文书籍之前,大脑必须先记住这本书读到了多少页的第多少行,等查完单词之后,能够继续读这本书。这样的切换是会影响读 书效率的,同样上下文切换也会影响多线程的执行速度。

           在理解这个之前,要理解程序计数器的作用(以下摘抄来自《深入理解java虚拟机》):

           程序计数器是一块较小的内存空间,它可以看作是当前线程所执行字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。且由于java虚拟机的多线程是通过线程轮流切换并分配器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器是一个内核)都只会执行一条线程中的指令,因为为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,我们称这类区域为“线程私有”的内存。

           线程切换时需要知道在这之前当前线程已经执行到哪条指令了,所以需要记录程序计数器的值,另外比如说线程正在进行某个计算的时候被挂起了,那么下次继续执行的时候需要知道之前挂起时变量的值时多少,因此需要记录CPU寄存器的状态。所以一般来说,线程上下文切换过程中会记录程序计数器、CPU寄存器状态等数据

    上下文切换代码测试

    下面的代码演示串行和并行执行并累加操作的时间:

    public class ContextSwitchTest
    {
        private static final long count = 10000;
        
        public static void main(String[] args) throws Exception
        {
            concurrency();
            serial();
        }
        
        private static void concurrency() throws Exception
        {
            long start = System.currentTimeMillis();
            Thread thread = new Thread(new Runnable(){
                public void run()
                {
                    int a = 0;
                    for (int i = 0; i < count; i++)
                    {
                        a += 5;
                    }
                }
            });
            thread.start();
            int b = 0;
            for (long i = 0; i < count; i++)
            {
                b --;
            }
            thread.join();
            long time = System.currentTimeMillis() - start;
            System.out.println("Concurrency:" + time + "ms, b = " + b);
        }
        
        private static void serial()
        {
            long start = System.currentTimeMillis();
            int a = 0;
            for (long i = 0; i < count; i++)
            {
                a += 5;
            }
            int b = 0;
            for (int i = 0; i < count; i++)
            {
                b --;
            }
            long time = System.currentTimeMillis() - start;
            System.out.println("Serial:" + time + "ms, b = " + b + ", a = " + a);
        }
    }

    修改上面的count值,即修改循环次数,看一下串行运行和并发运行的时间测试结果:

    循环次数串行执行耗时/ms并发执行耗时/ms串行和并发对比
    1亿7850并发快约0.5倍
    1000万106并发快约0.5~1倍
    100万32差不多
    10万22差不多
    1万01差不多,十几次执行下来,总体而言串行略快

    从表中可以看出,100次并发执行累加以下,串行执行和并发执行的运行速度总体而言差不多,1万次以下串行执行甚至还可以说是略快。为什么并发执行的速度会比串行慢呢?这就是因为线程有创建和上下文切换的开销

     引起上下文切换的原因

    • 1.时间片用完,CPU正常调度下一个任务
    • 2.被其他优先级更高的任务抢占
    • 3.执行任务碰到IO阻塞,调度器挂起当前任务,切换执行下一个任务
    • 4.用户代码主动挂起当前任务让出CPU时间
    • 5.多任务抢占资源,由于没有抢到被挂起
    • 6.硬件中断

    如何减少上下文切换

    既然上下文切换会导致额外的开销,因此减少上下文切换次数便可以提高多线程程序的运行效率。减少上下文切换的方法有无锁并发编程、CAS算法、使用最少线程和使用协程。

    • 无锁并发编程。多线程竞争时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash取模分段,不同的线程处理不同段的数据
    • CAS算法。Java的Atomic包使用CAS算法来更新数据,而不需要加锁
    • 使用最少线程。避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态
    • 协程。在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换
    展开全文
  • 这就是因为线程的上下文切换导致了额外的开销,使用 Synchronized 锁关键字,导致了资源竞争,从而引起上下文切换,但即使不使用 Synchronized 锁关键字,并发的执行速度也无法超越串联的执行速度,这是因为多线程...
  • 文章目录基本概念上下文原子为什么会有上下文这种概念进程上下文中断上下文进程上下文 VS 中断上下文原子上下文 基本概念 上下文   上下文是从英文context翻译过来,指的是一种环境。相对于进程而言,就是进程执行...
  • 线程上下文切换

    千次阅读 2018-08-29 10:05:04
    一、为什么要减少线程上下文切换  当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为...
  • 线程数量设置太大,可能带来资源的过度竞争,导致上下文切换,带来的额外的系统开销 上下文切换 1.在单处理器时期,操作系统就能处理多线程并发任务,处理器给每个线程分配CPU时间片,线程在CPU时间片内执行任务...
  • 谈论进程上下文 、中断上下文 、 原子上下文之前,有必要讨论下两个概念: a -- 上下文  上下文是从英文context翻译过来,指的是一种环境。相对于进程而言,就是进程执行时的环境;  具体来说就是各个变量和数据,...
  • 先前的研究集中于空间方面的共现或上下文,其中很少考虑时间方面的上下文。 在本文中,考虑到共现,上下文和移动性周期性,我们针对此问题提出了一种新颖的社会关系预测方法,称为多视图上下文共现(MVCC)。 ...
  • 先在主机通过top、free、ps、iostat 等常用工具分析了下主机的CPU、内存、IO使用情况,发现三者都不高。通过vmstat 1 查看的结果如下:   从vmstat的输出结果来看,io项的block in 和block ...
  • 虽然并不是真正意义的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行。 再后来发展到多线程技术,使得在一个程序...
  • Java多线程--上下文切换

    千次阅读 2017-09-03 15:09:06
    在进行并发编程时,如果希望通过多线程执行任务让程序运行得更快,会面临非常多的挑战,比如上下文切换的问题、死锁的问题,以及受限于硬件和软件的资源限制问题,本文要研究的是上下文切换的问题。 1.什么是...
  • 本文主要集中介绍 进程、线程、软硬中断、以及进程上下文、中断上下文等信息 一 :Tasklet机制: 1.1定义 : Tasklet 是 Linux中断处理机制中的 软中断延迟机制,在Linux中存在着硬中断和软中断之别在Linux 接收到 ...
  • Linux内核之进程上下文和中断上下文

    千次阅读 2017-04-03 15:23:16
    进程在执行的过程中始终会处于用户态和内核态中的一种,而内核态又分为运行于进程上下文(内核代表进程运行于内核空间)和中断上下文(内核代表硬件运行于内核空间)。 进程上下文 所谓的进程上下文就是进程在执行的...
  • 本质原因是:上下文切换 当然更准确的说是:过多的上下文切换是导致平均负载升高的凶手。正常的上下文切换是系统调度任务的必要手段。 1.什么是上下文? 任务中的CPU寄存器,程序计数器都是上下文,可以理解为...
  • 谈论进程上下文 、中断上下文 、 原子上下文之前,有必要讨论下两个概念: a -- 上下文 上下文是从英文context翻译过来,指的是一种环境。相对于进程而言,就是进程执行时的环境; 具体来说就是各个变量和数据,...
  • 通过上一讲的讲解,相信你对上下文切换已经有了一定的了解了。如果是单个线程,在 CPU 调用之后,那么它基本上是不会被调度出去的。如果可运行的线程数远大于 CPU 数量,那...
  • js执行上下文

    千次阅读 2019-05-22 10:03:18
    1、内存空间 内存空间大家都比较熟,即栈与堆。 JS的基础数据类型有Undefined、Null、Boolean、Number、String,这些都是按值访问,存放在栈内存。...2、JS代码的执行环境(执行上下文,Execution Con...
  • 线程的上下文切换 上下文切换 1.对于CPU而言,在一个时刻只能运因自身原因被迫暂停运行,此时另一个线程会被操作系统选中来占用处理器行一个线程,当一个线程的时间片用完,或者 2.当CPU结束运行一个线程,转去...
  • 安卓Context上下文对象 在开发中很多地方都会用到Context,相信很多读者都是会一知半解的,那么在安卓中&amp;quot;上下文&amp;quot;是指什么意思? 首先我们要回顾下,在我们大语文中,上下文我们可以理解为...
  • 异步调用Feign上下文丢失问题

    千次阅读 2020-10-24 09:55:02
    由于一些业务处理,在远程调用Feign时,需要异步调用,但是当前请求上下文是保存在ThreadLocal中,这样会导致上下文丢失。 公司业务需要在批量导入数据,文件上传成功,异步解析数据入库。 feign 拦截器配置如下 在...
  • 什么是上下文切换   即使是单核 CPU 也是支持多线程技术的,CPU 通过给每个线程分配一定量的 CPU 时间片来实现这个机制。时间片是 CPU 分配给各个线程的时间,因为时间片非常短,所以 CPU 通过不停地切换线程...
  • 一、问题现象 ...先在主机通过top、free、ps、iostat 等常用工具分析了下主机的CPU、内存、IO使用情况,发现三者都不高。通过vmstat 1 查看的结果如下: 从vmstat的输出结果来看,io项的block
  • 对于服务器的优化,很多人都有自己的经验和见解,但就我观察,有两点常常会被人忽视 – 上下文切换 和 Cache Line同步 问题,人们往往都会习惯性地把视线集中在尽力减少内存拷贝,减少IO次数这样的问题上,不可否认...
  • 基本功:线程上下文切换

    万次阅读 多人点赞 2019-05-31 22:06:42
    更多的线程意味着线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。可以看另一篇《Java从线程安全到synchronized和Lock探索》 时间片 多任务系统往往需要同时执行多道作业。作业数往往大于...
  •  什么是CPU上下文切换?  现在linux是大多基于抢占式,CPU给每个任务一定的服务时间,当时间片轮转的时候,需要把当前状态保存下来,同时加载下一个任务,这个过程叫做上下文切换。时间片轮转的方式,使得多个...
  • 一、上下文切换 即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程...
  • python上下文管理器ContextLib及with语句

    千次阅读 2016-01-01 12:30:42
    :由上下文管理器创建,通过上下文管理器的 __enter__() 和__exit__() 方法实现,__enter__() 方法在语句体执行之前进入运行时上下文,__exit__() 在语句体执行完后从运行时上下文退出。with 语句支持运行时上下文这...
  • 进程上下文和中断上下文是操作系统中很重要的两个概念,这两个概念在操作系统课程中不断被提及,是最经常接触、看上去很懂但又说不清楚到底怎么回事。造成这种局面的原因,可能是原来接触到的操作系统课程的教学总...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 108,287
精华内容 43,314
关键字:

引起上下文