多线程也不一定比单线程快

多线程似乎一直给我们这样的印象就是多线程比单线程快,其实这是一个伪命题.事无绝对,多线程有时候确实比单线程快,但也有很多时候没有单线程那么快. 首先简单区分一下并发性(concurrency)和并行性(parallel).并行是说同一时刻有多条命令在多个处理器上同时执行.并发是说同一时刻只有一条指令执行,只不过进程(线程)指令在CPU中快速轮换,速度极快,给人看起来就是”同时运行”的印象,实际上同一时刻只有一条指令进行. 但实际上如果我们在一个应用程序中使用了多线程,线程之间的轮换以及上下文切换是需要花费很多时间的,这样的话当我们执行类似循环之类的操作的时候,是不是就意味着单线程一定会比多线程快呢(因为单线程的执行没有线程切换的时间消耗),看下面一段代码(出自<<Java并发编程的艺术>>)

public class ConcurrencyTest {
    private static final long count = 1000000000;

    public static void main(String[] args) {
        try {
            concurrency();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        serial();
    }

    private static void concurrency() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                 int a = 0;
                 for (long 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 (long i = 0; i < count; i++)
        {
            b--;
        }
        long time = System.currentTimeMillis() - start;
        System.out.println("concurrency : " + time + "ms,b=" + b);
    }

}


这段代码的运行结果是当count值比较小的时候单线程的运行速度比多线程要快,当count的值比较大的时候多线程的速度大概会是单线程的两倍为什么会这样呢,理论上来说执行上述这种代码操作单线程不需要上下文切换应该肯定比多线程要快才对呀.
 其实是因为我们异想天开了,CPU的资源又不是全部都给你这个Java程序使用的,别的程序也要占用CPU资源啊.比如说当我们这个程序还没有运行的时候其实可能操作系统中已经有50个线程在运行了,那么当我们这个程序运行的时候,单线程就会占用CPU51分之1的时间(假设每个线程占用时间相等),多线程就会占用CPU52分之2的时间,你说哪个会运行的更快呢.当然当数量比较少的时候上下文之间的轮换会占用相对较多的时间所以这个时候虽然多线程占用CPU52分之2的时间,但是切换也需要很多的时间所以就比单线程要慢
.

原文地址:https://www.cnblogs.com/amiezhang/p/11285781.html

时间: 2024-07-30 08:35:33

多线程也不一定比单线程快的相关文章

多线程并发一定比单线程快吗?

很多时候我们都以为要想处理速度更快,那就多开几个线程跑! 确实多线程在一定情况下比单线程更快. 下面的代码演示串行和并发执行并累加操作的时间,请分析:下面的代码并发执行一定比串行执行快吗?当count的数量增加 1万 -> 10万 -> 100万 -> 1000万 -> 1亿 1 public class ConcurrencyTest { 2 private static final long count = 10000l; 3 4 public static void main

python多线程不能利用多核cpu,但有时候多线程确实比单线程快。

python 为什么不能利用多核 CPU  GIL 其实是因为在 python中有一个 GIL( Global Interpreter Lock),中文为:全局解释器锁.  1.最开始时候设计GIL是为了数据安全 python为了数据安全设计了这个 GIL. 2.每个 CPU在同一时间只能执行一个线程: (在单核 CPU下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念. 但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生:而并发是指两个或多个事件在同

Python多线程和多进程谁更快?

python多进程和多线程谁更快 python3.6 threading和multiprocessing 四核+三星250G-850-SSD 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很多都说python多进程更快,因为GIL(全局解释器锁).但是我在写代码的时候,测试时间却是多线程更快,所以这到底是怎么回事?最近再做分词工作,原来的代码速度太慢,想提速,所以来探求一下有效方法(文末有代码和效果图) 这里先来一张程序的结果图,说明线程和进程谁更快 一些定义 并行是指两个或者多个事件

多线程中的上下文切换

相信大家在面试的时候,都经常会被问到这个问题 – “多线程的速度一定比单线程快吗”.这么问也就说明答案是否定的,而这道题的精髓就在于你能不能说出上下文切换这几个字.那什么是上下文切换呢? 上下文切换定义1:即使是单核的cpu也能够执行多线程,cpu通过给每个线程分配时间片来实现这个机制.时间片是cpu分配给各个线程的时间,因为时间非常短,所以cpu通过不断地切换线程,让我们感觉多个线程是同时执行的,一般时间片为几十毫秒. cpu通过时间片分配算法来循环执行任务,当前任务执行一个时间片后切换到下一

C# 面试知识点总结

1,事件是对象,委托时类型.事件内部其实就是一个private 的委托和add,remove两个方法. 2.override 和overload的区别: override是对基类中方法的重写,是会覆盖的,是面向对象的概念.而overload是因为函数名称相同,参数或类型不同,是面向过程的概念. 3.索引器 4.属性和pulic字段的不同:属性可以对设置属性时做非法值判断,就是可以卡一些条件. 5.三层架构: 目的:高内聚.低耦合.上层代码必须在下层代码提供接口后才能开发. 表现层(UI):展现给

C#面试基础题1

1.简述 private. protected. public. internal 修饰符的访问权限.(C++中没有internal) private : 私有成员, 在类的内部才可以访问 ,也就是类内部的函数等成员可以访问. protected : 保护成员,该类内部和继承类中可以访问. public : 公共成员,完全公开,没有访问限制. internal: 当前程序集内可以访问. 2.C#中的委托是什么?事件是不是一种委托?事件和委托的关系. 委托可以把一个方法作为参数代入另一个方法.委托

c#面试题汇总

下面的参考解答只是帮助大家理解,不用背,面试题.笔试题千变万化,不要梦想着把题覆盖了,下面的题是供大家查漏补缺用的,真正的把这些题搞懂了,才能“以不变应万变”.回答问题的时候能联系做过项目的例子是最好的,有的问题后面我已经补充联系到项目中的对应的案例了. 1.简述 private. protected. public. internal 修饰符的访问权限. private : 私有成员, 在类的内部才可以访问 ,也就是类内部的函数等成员可以访问. protected : 保护成员,该类内部和继承

Python 巧妙的实现并行

需求 给定一个list   针对list 中每个元素执行一定的操作(这个操作很费时间,例如爬数据的时候调用某个网站的接口),返回操作后的list 例如 给定 1-10个数,在每个数字后面加个字母a 方法 1.利用线程池pool 及map 函数 实现 1 from multiprocessing import Pool 2 from multiprocessing.dummy import Pool as ThreadPool 3 import time 4 pool = ThreadPool(1

第一章 并发编程的挑战

挑战一:上下文切换 多线程一定比单线程快么? public class ConcurrencyTest { private static final long count = 10001; public static void main(String[] args) throws InterruptedException { concurrency(); serial(); } private static void concurrency() throws InterruptedExcepti