精华内容
下载资源
问答
  • 为此我们可以使用多线程或者多进程来处理。 首先声明一点! 多线程和多进程是不一样的!一个是 thread 库,一个是 multiprocessing 库。而多线程 thread 在 Python 里面被称作鸡肋的存在!而没错!本节介绍的是就是...

    前言
    我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理。 首先声明一点! 多线程和多进程是不一样的!一个是 thread 库,一个是 multiprocessing 库。而多线程 thread 在 Python 里面被称作鸡肋的存在!而没错!本节介绍的是就是这个库 thread。 不建议你用这个,不过还是介绍下了,如果想看可以看看下面,不想浪费时间直接看 multiprocessing 多进程

    鸡肋点
    名言:
    “Python 下多线程是鸡肋,推荐使用多进程!”

    那当然有同学会问了,为啥?

    背景
    1、GIL 是什么? GIL 的全称是 Global Interpreter Lock (全局解释器锁),来源是 python 设计之初的考虑,为了数据安全所做的决定。 2、每个 CPU 在同一时间只能执行一个线程(在单核 CPU 下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。) 在 Python 多线程下,每个线程的执行方式:

    获取 GIL
    执行代码直到 sleep 或者是 python 虚拟机将其挂起。
    释放 GIL
    可见,某个线程想要执行,必须先拿到 GIL,我们可以把 GIL 看作是 “通行证”,并且在一个 python 进程中,GIL 只有一个。拿不到通行证的线程,就不允许进入 CPU 执行。 在 Python2.x 里,GIL 的释放逻辑是当前线程遇见 IO 操作或者 ticks 计数达到 100(ticks 可以看作是 Python 自身的一个计数器,专门做用于 GIL,每次释放后归零,这个计数可以通过 sys.setcheckinterval 来调整),进行释放。 而每次释放 GIL 锁,线程进行锁竞争、切换线程,会消耗资源。并且由于 GIL 锁存在,python 里一个进程永远只能同时执行一个线程 (拿到 GIL 的线程才能执行),这就是为什么在多核 CPU 上,python 的多线程效率并不高。

    那么是不是 python 的多线程就完全没用了呢?
    在这里我们进行分类讨论: 1、CPU 密集型代码 (各种循环处理、计数等等),在这种情况下,由于计算工作多,ticks 计数很快就会达到阈值,然后触发 GIL 的释放与再竞争(多个线程来回切换当然是需要消耗资源的),所以 python 下的多线程对 CPU 密集型代码并不友好。 2、IO 密集型代码 (文件处理、网络爬虫等),多线程能够有效提升效率 (单线程下有 IO 操作会进行 IO 等待,造成不必要的时间浪费,而开启多线程能在线程 A 等待时,自动切换到线程 B,可以不浪费 CPU 的资源,从而能提升程序执行效率)。所以 python 的多线程对 IO 密集型代码比较友好。 而在 python3.x 中,GIL 不使用 ticks 计数,改为使用计时器(执行时间达到阈值后,当前线程释放 GIL),这样对 CPU 密集型程序更加友好,但依然没有解决 GIL 导致的同一时间只能执行一个线程的问题,所以效率依然不尽如人意。

    多核性能
    多核多线程比单核多线程更差,原因是单核下多线程,每次释放 GIL,唤醒的那个线程都能获取到 GIL 锁,所以能够无缝执行,但多核下,CPU0 释放 GIL 后,其他 CPU 上的线程都会进行竞争,但 GIL 可能会马上又被 CPU0 拿到,导致其他几个 CPU 上被唤醒后的线程会醒着等待到切换时间后又进入待调度状态,这样会造成线程颠簸 (thrashing),导致效率更低

    多进程为什么不会这样?
    每个进程有各自独立的 GIL,互不干扰,这样就可以真正意义上的并行执行,所以在 python 中,多进程的执行效率优于多线程 (仅仅针对多核 CPU 而言)。 所以在这里说结论:多核下,想做并行提升效率,比较通用的方法是使用多进程,能够有效提高执行效率。

    目标网站https://image.so.com
    在这里插入图片描述
    将类别为图中红框中的图片,下载保存到本地。

    1**.单线程代码**

    import requests
    from my_test import settings
    import sys
    import time
    import pymysql
    
    
    class DownLoadPictures(object):
        def __init__(self, sn):
            self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                                          '(KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36',
                            'Referer': 'https://image.so.com/z?ch=beauty'}
            self.url = 'https://image.so.com/zjl?ch=beauty&sn={}'.format(sn)
    
            self.conn = pymysql.Connect(**settings.MYSQL_CONFIG)
            self.cursor = self.conn.cursor()
    
        def __del__(self):
            self.cursor.close()
            self.conn.close()
    
        def get_resp_data(self):
            print('当前是链接为{}的图片下载!'.format(self.url))
            # 返回的数据在json里
            resp = requests.get(self.url, headers=self.headers)
            return resp.json()
    
        def get_download_url(self):
            resp_data = self.get_resp_data()
            # 判断是否还有图片
            if resp_data['end'] is False:
                for elem in resp_data['list']:
                    downloadurl = elem['qhimg_downurl']
                    fromUrl = elem['purl']
                    title = elem['title']
                    self.download_picture(downloadurl, title, fromUrl)
            else:
                print('链接为{}已无图片'.format(self.url))
    
        def download_picture(self, downloadurl, title, fromUrl):
            sql = "select * from beautyImages where downloadUrl = '{}' and title='{}'".format(downloadurl, title)
            row_count = self.cursor.execute(sql)
            if not row_count:
                try:
                    resp = requests.get(downloadurl, headers=self.headers)
                    if resp.status_code == requests.codes.ok:
                        with open(settings.STORE_PATH + '/' + title + '.jpg', 'wb') as f:
                            f.write(resp.content)
                    print('下载完成')
                    # 插入数据库
                    insert_sql = "INSERT INTO beautyImages(title, downloadUrl, fromUrl, createTime) values (%s, %s, %s, %s)"
                    try:
                        self.cursor.execute(insert_sql, (title, downloadurl, fromUrl, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())))
                        self.conn.commit()
                        print('插入标题为{}, 链接为{}成功!'.format(title, downloadurl))
                    except Exception:
                        print('插入标题为{}, 链接为{}失败, 失败原因是{}'.format(title, downloadurl, sys.exc_info()[1]))
                except Exception:
                    print('标题为{}, 链接为{}下载失败,失败原因是{}'.format(title, downloadurl, sys.exc_info()[1]))
            else:
                print('标题为{}, 链接为{}已存在'.format(title, downloadurl))
    
    
    if __name__ == '__main__':
        start_time = time.time()
        for i in range(0, 301, 30):
            test = DownLoadPictures(sn=i)
            test.get_download_url()
        use_time = time.time() - start_time
        print('单线程用时:{}秒'.format(use_time))
    
    

    单线程程序运行结果为
    在这里插入图片描述

    在单线程的情况下,爬取和下载这十一个链接共花费了236s左右的时间。共获取了329张图片。
    在这里插入图片描述

    在这里插入图片描述

    2.多线程代码

    import requests
    from my_test import settings
    import sys
    import time
    import pymysql
    import threading
    
    
    # 继承父类threading.Thread
    class DownLoadPictures(threading.Thread):
        def __init__(self, name, sn):
            super().__init__()
            self.name = name
            self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                                          '(KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36',
                            'Referer': 'https://image.so.com/z?ch=beauty'}
            self.url = 'https://image.so.com/zjl?ch=beauty&sn={}'.format(sn)
    
            self.conn = pymysql.Connect(**settings.MYSQL_CONFIG)
            self.cursor = self.conn.cursor()
    
        def __del__(self):
            self.cursor.close()
            self.conn.close()
    
        def get_resp_data(self):
            # print('当前是链接为{}的图片下载!'.format(self.url))
            print('当前是线程为{}的图片下载!'.format(self.name))
            # 返回的数据在json里
            resp = requests.get(self.url, headers=self.headers)
            return resp.json()
    
        def run(self):
            # 重写run函数,线程在创建后会直接运行run函数
            resp_data = self.get_resp_data()
            # 判断是否还有图片
            if resp_data['end'] is False:
                for elem in resp_data['list']:
                    downloadurl = elem['qhimg_downurl']
                    fromUrl = elem['purl']
                    title = elem['title']
                    self.download_picture(downloadurl, title, fromUrl)
            else:
                print('链接为{}已无图片'.format(self.url))
    
        def download_picture(self, downloadurl, title, fromUrl):
            sql = "select * from beautyImages where downloadUrl = '{}' and title='{}'".format(downloadurl, title)
            row_count = self.cursor.execute(sql)
            if not row_count:
                try:
                    resp = requests.get(downloadurl, headers=self.headers)
                    if resp.status_code == requests.codes.ok:
                        with open(settings.STORE_PATH + '/' + title + '.jpg', 'wb') as f:
                            f.write(resp.content)
                    print('下载完成')
                    # 插入数据库
                    insert_sql = "INSERT INTO beautyImages(title, downloadUrl, fromUrl, createTime) values (%s, %s, %s, %s)"
                    try:
                        self.cursor.execute(insert_sql, (title, downloadurl, fromUrl, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())))
                        self.conn.commit()
                        print('插入标题为{}, 链接为{}成功!'.format(title, downloadurl))
                    except Exception:
                        print('插入标题为{}, 链接为{}失败, 失败原因是{}'.format(title, downloadurl, sys.exc_info()[1]))
                except Exception:
                    print('标题为{}, 链接为{}下载失败,失败原因是{}'.format(title, downloadurl, sys.exc_info()[1]))
            else:
                print('标题为{}, 链接为{}已存在'.format(title, downloadurl))
    
    
    if __name__ == '__main__':
        start_time = time.time()
        thread_list = []
        for i in range(0, 301, 30):
            test = DownLoadPictures(name=str(i), sn=i)
            thread_list.append(test)
        for t in thread_list:
            t.start()
        for t in thread_list:
            t.join()
        use_time = time.time() - start_time
        print('多线程用时:{}秒'.format(use_time))
    

    多线程程序运行结果为:
    在这里插入图片描述
    在多线程的情况下,爬取和下载这十一个链接共花费了31左右的时间。共获取了330张图片。

    在这里插入图片描述
    在这里插入图片描述

    8.总结
    两份代码都是执行同一个任务,爬取360美女图片300多张图片并保存。但单线程程序花了236多的时间,而多线程程序只用了31s就完成了,大大提升了效率。

    亲测有效,本文章全系对技术的兴趣爱好,欢迎大家学习交流。

    展开全文
  • 如果是IO密集型,多线程进程可以利用IO阻塞等待时的空闲时间执行其他线程,提升效率。所以我们根据实验对比不同场景的效率(1)引入所需要的模块import requestsimport timefrom threading import Threadfr...

    对比实验

    资料显示,如果多线程的进程是CPU密集型的,那多线程并不能有多少效率上的提升,相反还可能会因为线程的频繁切换,导致效率下降,推荐使用多进程;如果是IO密集型,多线程进程可以利用IO阻塞等待时的空闲时间执行其他线程,提升效率。所以我们根据实验对比不同场景的效率

    (1)引入所需要的模块import requests

    import time

    from threading import Thread

    from multiprocessing import Process

    (2)定义CPU密集的计算函数def count(x, y):

    # 使程序完成150万计算

    c = 0

    while c < 500000:

    c += 1

    x += x

    y += y

    (3)定义IO密集的文件读写函数def write():

    f = open("test.txt", "w")

    for x in range(5000000):

    f.write("testwrite\n")

    f.close()

    def read():

    f = open("test.txt", "r")

    lines = f.readlines()

    f.close()

    (4) 定义网络请求函数_head = {

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'}

    url = "http://www.tieba.com"

    def http_request():

    try:

    webPage = requests.get(url, headers=_head)

    html = webPage.text

    return {"context": html}

    except Exception as e:

    return {"error": e}

    (5)测试线性执行IO密集操作、CPU密集操作所需时间、网络请求密集型操作所需时间# CPU密集操作

    t = time.time()

    for x in range(10):

    count(1, 1)

    print("Line cpu", time.time() - t)

    # IO密集操作

    t = time.time()

    for x in range(10):

    write()

    read()

    print("Line IO", time.time() - t)

    # 网络请求密集型操作

    t = time.time()

    for x in range(10):

    http_request()

    print("Line Http Request", time.time() - t)

    输出

    CPU密集:95.6059999466、91.57099986076355 92.52800011634827、 99.96799993515015

    IO密集:24.25、21.76699995994568、21.769999980926514、22.060999870300293

    网络请求密集型: 4.519999980926514、8.563999891281128、4.371000051498413、4.522000074386597、14.671000003814697

    (6)测试多线程并发执行CPU密集操作所需时间counts = []

    t = time.time()

    for x in range(10):

    thread = Thread(target=count, args=(1,1))

    counts.append(thread)

    thread.start()

    e = counts.__len__()

    while True:

    for th in counts:

    if not th.is_alive():

    e -= 1

    if e <= 0:

    break

    print(time.time() - t)

    Output: 99.9240000248 、101.26400017738342、102.32200002670288

    (7)测试多线程并发执行IO密集操作所需时间def io():

    write()

    read()

    t = time.time()

    ios = []

    t = time.time()

    for x in range(10):

    thread = Thread(target=count, args=(1,1))

    ios.append(thread)

    thread.start()

    e = ios.__len__()

    while True:

    for th in ios:

    if not th.is_alive():

    e -= 1

    if e <= 0:

    break

    print(time.time() - t)

    Output: 25.69700002670288、24.02400016784668

    (8)测试多线程并发执行网络密集操作所需时间t = time.time()

    ios = []

    t = time.time()

    for x in range(10):

    thread = Thread(target=http_request)

    ios.append(thread)

    thread.start()

    e = ios.__len__()

    while True:

    for th in ios:

    if not th.is_alive():

    e -= 1

    if e <= 0:

    break

    print("Thread Http Request", time.time() - t)

    Output: 0.7419998645782471、0.3839998245239258、0.3900001049041748

    (9)测试多进程并发执行CPU密集操作所需时间counts = []

    t = time.time()

    for x in range(10):

    process = Process(target=count, args=(1,1))

    counts.append(process)

    process.start()

    e = counts.__len__()

    while True:

    for th in counts:

    if not th.is_alive():

    e -= 1

    if e <= 0:

    break

    print("Multiprocess cpu", time.time() - t)

    Output: 54.342000007629395、53.437999963760376

    (10)测试多进程并发执行IO密集型操作t = time.time()

    ios = []

    t = time.time()

    for x in range(10):

    process = Process(target=io)

    ios.append(process)

    process.start()

    e = ios.__len__()

    while True:

    for th in ios:

    if not th.is_alive():

    e -= 1

    if e <= 0:

    break

    print("Multiprocess IO", time.time() - t)

    Output: 12.509000062942505、13.059000015258789

    (11)测试多进程并发执行Http请求密集型操作t = time.time()

    httprs = []

    t = time.time()

    for x in range(10):

    process = Process(target=http_request)

    ios.append(process)

    process.start()

    e = httprs.__len__()

    while True:

    for th in httprs:

    if not th.is_alive():

    e -= 1

    if e <= 0:

    break

    print("Multiprocess Http Request", time.time() - t)

    Output: 0.5329999923706055、0.4760000705718994

    实验结果

    通过上面的结果,我们可以看到:

    多线程在IO密集型的操作下似乎也没有很大的优势(也许IO操作的任务再繁重一些就能体现出优势),在CPU密集型的操作下明显地比单线程线性执行性能更差,但是对于网络请求这种忙等阻塞线程的操作,多线程的优势便非常显著了

    多进程无论是在CPU密集型还是IO密集型以及网络请求密集型(经常发生线程阻塞的操作)中,都能体现出性能的优势。不过在类似网络请求密集型的操作上,与多线程相差无几,但却更占用CPU等资源,所以对于这种情况下,我们可以选择多线程来执行

    本文原创发布php中文网,转载请注明出处,感谢您的尊重!

    展开全文
  • Node.js采用事件驱动和异步I/O的方式,实现了一个单线程、高并发的运行时环境,而单线程就意味着同一时间只能做一件事。nodejs实现异步、非阻塞:nodejs其实只有js执行是单线程,I/O显然是其它线程。js执行线程是...

    node是单线程的,采用单线程异步非阻塞模式。因为javascript引擎的关系,node默认是单线程,一个node.js应用无法利用多核资源。

    Node.js采用事件驱动和异步I/O的方式,实现了一个单线程、高并发的运行时环境,而单线程就意味着同一时间只能做一件事。

    nodejs实现异步、非阻塞:

    nodejs其实只有js执行是单线程,I/O显然是其它线程。

    js执行线程是单线程,把需要做的I/O交给libuv,自己马上返回做别的事情,然后libuv在指定的时刻回调就行了。

    细化一点,nodejs会先从js代码通过node-bindings调用到C/C++代码,然后通过C/C++代码封装一个叫 “请求对象” 的东西交给libuv,这个请求对象里面无非就是需要执行的功能+回调之类的东西,给libuv执行以及执行完实现回调。

    总结来说,一个异步 I/O 的大致流程如下:

    1、发起 I/O 调用

    用户通过 Javascript 代码调用 Node 核心模块,将参数和回调函数传入到核心模块;

    Node 核心模块会将传入的参数和回调函数封装成一个请求对象;

    将这个请求对象推入到 I/O 线程池等待执行;

    Javascript 发起的异步调用结束,Javascript 线程继续执行后续操作。

    2、执行回调

    I/O 操作完成后,会取出之前封装在请求对象中的回调函数,执行这个回调函数,以完成 Javascript 回调的目的。(这里回调的细节下面讲解)

    从这里,我们可以看到,我们其实对 Node.js 的单线程一直有个误会。

    事实上,它的单线程指的是自身Javascript运行环境的单线程,Node.js并没有给Javascript执行时创建新线程的能力,最终的实际操作,还是通过Libuv以及它的事件循环来执行的。这也就是为什么 Javascript一个单线程的语言,能在Node.js里面实现异步操作的原因,两者并不冲突。

    展开全文
  • 该测试用例分别使用单线程多线程进行 a 的递增,b 的递减操作,我们通过控制循环次数,来比较相同次数下,串行和并行所花时间。 public class TimeTest { public final int count = 1000000; public stati

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

    我们知道,使用多线程,可以同时执行多个任务,从表面上看,多线程明显是要快于单线程的。但是,多线程的创建,上下文的切换也是需要开销的,所以多线程不一定比单线程快,接下来我们来看一个简单的测试用例。

    该测试用例分别使用单线程和多线程进行 a 的递增,b 的递减操作,我们通过控制循环次数,来比较相同次数下,串行和并行所花时间。

    public class TimeTest {
        public final int count = 1000000;
    
        public static void main(String[] args) throws InterruptedException {
            TimeTest timeTest = new TimeTest();
            System.out.println("执行 " + timeTest.count + " 次");
            timeTest.serial();	//串行
            timeTest.parallel();	//并行
        }
    
        public void serial() {
            int a = 0;
            int b = 0;
            long l = System.currentTimeMillis();
            for (int i = 0; i < count; i++) {
                a++;
            }
    
            for (int i = 0; i < count; i++) {
                b--;
            }
    
            System.out.println("串行----->" + (System.currentTimeMillis() - l));
        }
    
        public void parallel() throws InterruptedException {
            int b = 0;
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    int a = 0;
                    for (int i = 0; i < count; i++) {
                        a++;
                    }
                }
            });
            long l = System.currentTimeMillis();
            thread.start();
            for (int i = 0; i < count; i++) {
                b--;
            }
            thread.join();	//等thread线程执行完毕再输出时间差
            System.out.println("并行----->" + (System.currentTimeMillis() - l));
        }
    }
    

    输出结果:

    count100100001000005000001000000
    单线程(ms)00224
    多线程 (ms)00232

    由上表可以发现,执行次数在 50w 次左右,单线程比多线程快,100w 左右,多线程比单线程快,所以,多线程不一定比单线程快。

    注:以上测试结果对比可能不太明显,计算时间差时可以使用 System.nanoTime(),单位精确到纳秒级。

    展开全文
  • 文章目录进程和线程理论知识二者区别单线程多线程 进程和线程 由于理论概念难以理解,我在查资料的过程中经常能看到这样一个形象的比喻: 除此之外,也可以看一下阮一峰大神的一篇博客:进程线程的一个简单解释...
  • 学习爬虫的过程中为了提高爬取的速度之前一直使用多线程,近日研究了一下协程,协程也被认为是轻量级的线程,使用协程在I/O密集型运算中能够更好的缩短运行时间,因为协程是真正的实现了异步操作,并且对比多线程而...
  • 最近在B部门做项目,用到的平台框架都是基于进程模式的,在以前的A部门做过的项目都是多线程模式的,在使用的过程中,也思考了一些问题,引发了对这两种类型的线程的对比和自己的一些看法(仅是个人观点)。...
  • } 以上为线程执行的代码,写入150个10M的文件共用时间:10900000ms #include #include #include #include #include void saveFile(char* fileName); char* int2stirng(int number); int main() { int i = 0; char* ...
  • 一、单线程(单条循环)插入50000条记录:每执行一次就要访问一次数据库import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql....
  • 测评一下使用多线程、线程池和单线程情况下的效率 public class Main{ public static void main(String[] args) throws InterruptedException { List<Integer> l = new LinkedList<>(); ...
  • 相对于多线程而言,可以说 Redis 是单线程,但是这种说法也是不太准确的。为什么呢?下面来分析一下: 一、Redis 单线程到底指什么? 没错,大家所熟知的 Redis 确实是单线程模型,指的是执行 Redis 命令的核心...
  • JMH是Java性能测试工具,主要是对工程中一些方法进行一些基准测试,支持的时间单位为:nano / micro / milli / macro 二、JMH的Jar包 Java项目开始编写JMH实例时肯定要先知道引用的哪些Jar包,JMH使用引用Jar包如下...
  • 方案爬取某网站 20 页图片,每页大概 20~30 张图片该网站没有反爬措施爬虫全速爬取,不设置休眠时间依次爬取每页的图片链接,保存至一个列表中(对于单线程、多进程方案),保存至队列(对于多线程方案),这一步使用...
  • 来回答前同事的一部分问题首先你要知道redis除了持久化,几乎所有操作都是在操作内存,比如像简单的set get操作都非常快,具体快我觉得你可以自己来做一个benchmark,并不难如果你关注新闻的话可以知道双11阿里的...
  • 1、目标:输出类似 Windows 的命令行工具中 tree /F 命令所得到的目录树: 2、语言、算法: 所使用的计算机语言:Java 涉及算法:递归算法 ...分别使用单线程多线程实现此功能; 在线程开始时和线...
  • 一、前言今天我要给大家分享的是如何爬取中农网产品报价数据,并分别用普通的单线程多线程和协程来爬取,从而对比单线程多线程和协程在网络爬虫中的性能。目标URL:https://www.z...
  • 当对数据修改时,如果两个线程同时去修改同一条数据,这样产生的结果就不是我们预期的结果。这时候就需要对修改操作进行加锁,让jvm里同一时刻只能有一个线程能够执行修改方法。下面是一个未加锁的修改方法:...
  • 文章目录一、单线程与多线程的区别二、端口扫描程序设计1. 创建项目2. 界面设计3. 单线程代码4. 多线程代码三、端口扫描程序运行效果1. 单线程2. 多线程四、参考 一、单线程与多线程的区别 单线程: 每个正在运行的...
  • 文章目录认识线程概念线程的创建方式线程的第一种创建方式线程的第二种创建方式线程的第三种创建方式线程的第四种创建方式线程的创建速度单线程的创建速度多线程的创建速度 认识线程 概念 进程是系统分配资源的最小...
  • 大家注意审题:Redis是多线程还是单线程?这个问题你要从多个方面回答,如果你仅仅只回答 "单线程" 肯定是说不过去的,为什么呢?所以今天,栈长利用工作时间紧急把这个问题紧急梳理了下,希望对大家有帮助。1、...
  • 多线程与高并发,锁

    2021-07-20 09:41:22
    线程基本概念 **线程**:一个程序里不同的执行路径就叫做线程 新建线程的方式 1.Thread 2.Runnable 3.Executors.newCachedThrad(通过线程池的方式) /** * 1.新建线程的第一种方式,继承Thread */ static class ...
  • 8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?一、前言Android中线程分为主线程(UI线程)和子线程,主线程主要处理和界面相关的事情,而子线程则用于执行耗时操作。如果在主线程中...
  • 单线程与多线程排序 单线程排序 bool compare(long a, long b) { return a ; } #define NUMNUM 8000000L long int nums[NUMNUM]; //待排序数组(约32M) int main() { srandom(time(NULL)); for (unsigned long i = 0...
  • (没错,就是在一个线程中实现 并发)一、协程的基础认识,与多线程对比。如果直接介绍协程、异步,我想很多人是搞不明白的,但是说起多线程想必大多数人都是有所了解的。比如下面这个很简单的多线程:1) 多线程的并发...
  • 一、什么是归并排序归并排序又称合并排序,它是成功应用分治技术的一个完美例子。对于一个需要排序的数组A[0....下面是归并排序的例子图解:二、单线程实现归并排序packagecom.bob.algorithms.sort;importjava.util....
  • 我们偶尔会遇到业务层中我们需要同时修改张表的数据并且需要有序的执行,一般我们都会通过同步的方式,即单线程的方式来执行,可能会存在执行超时的异常,造成请求结果失败,即使成功了,前端也需要等待较长的时间...
  • import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent....多线程单线程 打印数字到100000 的速度对比 */ public class Demo2 { public s

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 129,393
精华内容 51,757
关键字:

多线程与单线程时间对比