多线程

利用多线程通过对业务优化实现性能优化—— 性能优化利用 Thread 的 join

你。 提交于 2020-03-17 07:37:25
我们可以使用 join方法做到将程序并行。 举个例子:我们在开发过程中往往会遇到这样的场景,就是一个非常复杂的业务逻辑里边,比方说订票,如果说飞机票和火车票作为一个组装行程。比方说我要去 莫斯科,我人在A地,然后我可以选择去B地坐飞机,但是A地到B地这一段,我想做高铁。如果这作为一个订单的话,就意味着,下单过程需要到12306去扣火车票,然后到航空公司去扣飞机票。 对于上边的下单的过程,可以选择串行,比方说先去 12306扣火车票,再去航空公司扣机票,最终将结果返回。其实我们知道,整个下单过程是非常复杂的,都要检验什么的,如果串行操作的话,是非常耗时的。 这个时候我们可以使用多线程来处理我们的下单过程,线程A去处理扣火车票,线程B去处理扣飞机票。最后将最终的结果返回。 通过上边的问题的描述,其实就能引出一个问题,那就是我们需要等两个线程执行完成以后才能返回结果。我们如何知道线程A有没有执行完成呢,我们如何知道B执行完了呢,我们什么时候才放回结果呢? 这个时候就可以使用 Thread 的 join()方法,它可以做到,让主线程创建完A和B线程以后,等待A 和 B 线程执行结束以后再开始执行。怎么做到呢? 就是 主线程分别给A和B都进行Join() 下边来写一个例子模仿,这样的场景问题: /** * @author angus * @create 2020-03-14 15:59 */

学习Java第三十天--多线程之线程池和同步锁

半城伤御伤魂 提交于 2020-03-16 18:21:05
线程池、Callable接口、Future接口、Lock接口、同步锁的使用方法 14.4 线程池 14.4.1 线程池概念 14.4.2 线程池原理 14.4.3 获取线程池 14.4.4 Callable接口 14.4.5 Future接口 14.4.6 线程的同步 14.4.7 线程的异步 14.4.8 Lock接口 14.4.8 重入锁 14.4.9 读写锁 14.4.10 ReentrantReadWriteLock 14.4 线程池 14.4.1 线程池概念 现有问题: 线程是宝贵的内存资源、单个线程约占1MB空间,过多分配易造成内存溢出; 频繁的创建及销毁线程会增加虚拟机回收频率、资源开销,造成程序性能下降; 线程池: 线程容器,可设定线程分配的数量上限; 将预先创建的线程对象存入池中,并重用线程池中的线程对象 避免频繁的创建和销毁; 14.4.2 线程池原理 将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程; 14.4.3 获取线程池 常用的线程池接口和类(所在包java.util.concurrent) Executor:线程池的顶级接口 ExecutorService:线程池接口,可通过submit(Runnable task)提交任务代码; Executors工厂类:通过此类可以获得一个线程池; 通过newFixedThreadPool

Java多线程同步屏障CyclicBarrierDemo对象

情到浓时终转凉″ 提交于 2020-03-16 18:05:58
一、概述 同步屏障可以使多条线程彼此等待,直到抵达某个公共的屏障点。线程之间彼此等待时已经抵达公共屏障点的线程不会继续往下执行,会在所有线程抵达公共屏障点之前一直阻塞。CyclicBarrierDemo对象可以重用,这点与上一篇中的CountDownLatch对象不同,CountDowLatch时不可重用的。 二、主要方法 CyclicBarrier(int parties):初始化一个包含指定parties数目的CyclicBarrier对象 int await() throws InterruptedException, BrokenBarrierException:强制阻塞线程,一直等待所有的parties线程都在同步屏障上调用了await()方法 int await(long time, DateUtil util):指定线程的等待时间,如果超时会抛出异常 void reset():重置对象,如果此时有线程在这个对象上阻塞,则会抛出异常 int getNumberWaiting(): 返回阻塞的线程数量。 三、代码示例 高速公路的建造:高速公路的建造不是从头到尾建造的,高速公路在规划后之后,会将规划路线分段施工,一般情况下一条完整的高速公路在施工时是好几段同时施工的。下面我们使用CyclicBarrierDemo对象来实现建造一条完整高速公路的场景。 如上图中所示

windows多线程同步--临界区

浪子不回头ぞ 提交于 2020-03-16 14:33:30
推荐参考博客: 秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念 ,一般操作系统书上面都有。 适用范围:它只能同步一个进程中的线程,不能跨进程同步。一般用它来做单个进程内的代码快同步,效率比较高 windows中与临界区有关的结构是 CRITICAL_SECTION,关于该结构体的内部结构可参考 here 使用时,主线程中要先初始化临界区,最后要删除临界区,具体使用见下面代码: 本文地址 从一个例子来说明:假设有三个线程都需要使用打印机,我们可以把打印的代码放到临界区,这样就可以保证每次只有一个线程在使用打印机。 #include<string> #include<iostream> #include<process.h> #include<windows.h> using namespace std; //定义一个临界区 CRITICAL_SECTION g_cs; //线程绑定的函数返回值和参数是确定的,而且一定要__stdcall unsigned __stdcall threadFun(void *param) { EnterCriticalSection(&g_cs);//进入临界区,如果有其他线程则等待 cout<<*(string *)(param)<<endl; LeaveCriticalSection(&g_cs);//退出临界区,其他线程可以进来了

并发编程之线程池合理配置

戏子无情 提交于 2020-03-16 11:49:26
某厂面试归来,发现自己落伍了!>>> 如何合理的配置线程池参数: 思考该问题首先明确两个任务类型的概念 CPU密集:该任务需要进行大量的计算,但是并没有阻塞,CPU在全速的运行。值得注意的是CPU密集型的任务只有在真正的多核CPU上才能更好的发挥作用(多线程技术),单核的CPU模拟多线程并不能提高任务的执行速度,因为CPU 的计算能力是有限的。 IO密集:指的是该任务的IO操作,也就是说会存在阻塞的情况。这种任务会导致CPU浪费很多时间在等待上,因此这种类型的任务使用多线程技术能更好的提高计算集的任务执速度,即使是单核的计算机采用模拟多线程技术也能减少CPU等待IO的阻塞时间。 具体配置参考如下: CPU密集型任务=CPU核数+1 IO密集型任务 = 2*CPU核数 来源: oschina 链接: https://my.oschina.net/u/3670669/blog/3195873

Linux 多线程通信

帅比萌擦擦* 提交于 2020-03-16 06:44:37
Linux 多线程通信 2008-03-13 11:01 19764人阅读 评论 (0) 收藏 举报 linux 多线程 thread join windows 编程 摘自资料(linux 与Windows不同) 线程间无需特别的手段进行通信,因为线程间可以共享数据结构,也就是一个全局变量可以被两个线程同时使用。不过要注意的是线程间需要做好同步,一般用mutex。可以参考一些比较新的UNIX/Linux编程的书,都会提到Posix线程编程,比如《UNIX环境高级编程(第二版)》、《UNIX系统编程》等等。 linux的消息属于IPC,也就是进程间通信,线程用不上。 linux用pthread_kill对线程发信号。 另:windows下不是用post..(你是说PostMessage吗?)进行线程通信的吧? windows用PostThreadMessage进行线程间通信,但实际上极少用这种方法。还是利用同步多一些 LINUX下的同步和Windows原理都是一样的。不过Linux下的singal中断也很好用。 用好信号量,共享资源就可以了。 使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式

python多线程和GIL全局解释器锁

让人想犯罪 __ 提交于 2020-03-16 06:36:55
1、线程 线程被称为轻量级进程,是最小执行单元,系统调度的单位。线程切换需要的资源一般,效率一般。 2、多线程 在单个程序中同时运行多个线程完成不同的工作,称为多线程 3、并发: 操作系统同时执行几个程序,这几个程序都由一个cpu处理,但在一个时刻点上只有一个程序在cpu上处理 4、并行: 操作系统同时执行2个程序,但是有两个cpu,每个cpu处理一个程序,叫并行 5、串行: 是指的我们从事某项工作是一个步骤一个步骤去实施 一、多线程 #python3是假的多线程,它不是真真正正的并行,其实就是串行,只不过利用了cpu上下文的切换而已 1 mport threading 2 import time 3 # def test1(): 4 # for i in range(10): 5 # time.sleep(1) #睡1s 6 # print('test1=========>%s' % i) 7 # 8 # 9 # def test2(): 10 # for i in range(10): 11 # time.sleep(1) 12 # print('test2=========>%s' % i) 13 # 14 # t1 = threading.Thread(target=test1) #定义一个线程 target=函数名 15 # t2 = threading.Thread

如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

二次信任 提交于 2020-03-16 02:26:09
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。 在 Java 中可以用 wait、notify 和 notifyAll 来实现线程间的通信。。举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓冲区中有内容待消费(不为空)。相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再为满。 我们可以利用wait()来让一个线程在某些条件下暂停运行。例如,在生产者消费者模型中,生产者线程在缓冲区为满的时候,消费者在缓冲区为空的时候,都应该暂停运行。如果某些线程在等待某些条件触发,那当那些条件为真时,你可以用 notify 和 notifyAll 来通知那些等待中的线程重新开始运行。不同之处在于,notify 仅仅通知一个线程,并且我们不知道哪个线程会收到通知,然而 notifyAll 会通知所有等待中的线程。换言之,如果只有一个线程在等待一个信号灯,notify和notifyAll都会通知到这个线程。但如果多个线程在等待这个信号灯,那么notify只会通知到其中一个,而其它线程并不会收到任何通知,而notifyAll会唤醒所有等待中的线程。 在这篇文章中你将会学到如何使用

爬虫18-多线程爬虫

杀马特。学长 韩版系。学妹 提交于 2020-03-15 22:35:26
import requests from lxml import etree from urllib import request import os from queue import Queue import threading class Procuder(threading.Thread): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" } def __init__(self,page_queue,img_queue,*args,**kwargs): super(Procuder, self).__init__(*args,**kwargs) self.page_queue = page_queue self.img_queue = img_queue def run(self): while True: if self.page_queue.empty(): break url = self.page_queue.get() self.parse_page(url) def parse_page(self,url): response =

java多线程(一)多线程基础

孤街浪徒 提交于 2020-03-15 17:13:12
转自: 平凡希 老师 https://www.cnblogs.com/xiaoxi/p/5845016.html 一、进程 进程是操作系统结构的基础;是一次程序的执行;是一个程序及其数据在处理机上顺序执行时所发生的活动。操作系统中,几乎所有运行中的任务对应一条进程(Process)。一个程序进入内存运行,即变成一个进程。进程是处于运行过程中的程序,并且具有一定独立功能。描述进程的有一句话非常经典—— 进程是系统进行资源分配和调度的一个独立单位。   进程是系统中独立存在的实体,拥有自己独立的资源,拥有自己私有的地址空间 。 进程的实质,就是程序在多道程序系统中的一次执行过程,它是动态产生,动态消亡的,具有自己的生命周期和各种不同的状态。进程具有并发性,它可以同其他进程一起并发执行,按各自独立的、不可预知的速度向前推进。  (注意,并发性(concurrency)和并行性(parallel)是不同的。并行指的是同一时刻,多个指令在多台处理器上同时运行。并发指的是同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,看起来就好像多个指令同时执行一样。)   进程由 程序 、 数据 和 进程控制块 三部分组成。 二、线程 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC)