精华内容
下载资源
问答
  • 并行线程间的数据问题
    千次阅读
    2021-03-08 06:19:40

    public class App {

    public static void main(String[] args) {

    List list = new ArrayList<>();

    for (int i = 0; i < 1000; i++) {

    list.add(i);

    }

    System.out.println(list.size());

    List list1 = new ArrayList<>();

    list.stream().forEach(x -> list1.add(x));

    System.out.println(list1.size());

    // List list2 = new ArrayList<>();

    // list.parallelStream().forEach(x -> list2.add(x));

    // System.out.println(list2.size());

    List list3 = list.parallelStream().collect(Collectors.toList());

    System.out.println(list3.size());

    }

    }

    并行Stream因为考虑效率问题,所以没有在意线程安全

    我们可以使用线程安全的数据流处理使数据同步

    原文:https://www.cnblogs.com/freeht/p/13080566.html

    更多相关内容
  • 行业分类-设备装置-合并执行大规模并行线程数据扩展优化方法
  • 并发和并行以及线程安全

    千次阅读 2022-01-27 21:03:11
    并发:指的是任务数>CPU核数,通过操作系统的各种任务调度算法,实现多个任务"一起执行"(实际上总有些任务不在执行,因为CPU切换...同步:是指线程在访问某一资源时,获得了资源的返回结果之后才会执行其他操作(强调.....

    目录

    并发

    并行

     同步和异步

     threading模块实现多线程.

    创建线程:

            threading.Thread(target=func)

            *参数target指定线程执行的任务(函数)

    注意:在做平台开发的时候,对象若不会再调用,可用"del"方法手动回收,节省内存空间.

     线程安全---多线程共享全局变量:

            线程之间是共用同一内存的,那么线程可以共享全局变量

            如何解决此类问题?控制线程,避免同时获取数据.

                    同步&互斥锁.

    threading模块中定义了Lock类,可以方便地处理锁定:

            #创建锁:

    mutex=threading.Lock()

            #锁定:上锁原则---->哪里需要锁,锁就上哪里

    mutex.acquire()

            #释放:

    mutex.release()


    并发

    并发:指的是任务数>CPU核数,通过操作系统的各种任务调度算法,实现多个任务"一起执行"(实际上总有些任务不在执行,因为CPU切换任务的速度非常快,看上去在一起执行而已).并发针对的是同一段时间内,有多个任务数在运行,强调同一段时间范围.

    并行

    并行:指的是任务数≤CPU核数,即任务真的在一起执行.并行针对的同一时刻有多个任务数在运行,强调的是同一时刻.

    并发与并行在CPU层面的表现:

     同步和异步

    同步:是指线程在访问某一资源时,获得了资源的返回结果之后才会执行其他操作(强调先做某件事,再做某件事).

    异步:与同步相对,是指线程在访问某一资源时,无论是否取得返回结果,都进行下一步操作;当有了资源返回结果时,系统自会通知线程.

     threading模块实现多线程.

    python的threading模块是对thread模块做了一些包装的,可以更方便我们使用.

    创建线程:

            threading.Thread(target=func)

            *参数target指定线程执行的任务(函数)

    注意:在做平台开发的时候,对象若不会再调用,可用"del"方法手动回收,节省内存空间.

    追查threading.Thread()源代码,发现,我们穿进去的target参数,最终被赋值为self._target,并且在用完了后,调用了python内置方法del,回收了无用的self._target,回收了内存空间. 

    threading模块的Thread类提供一下方法:

    run( )                用以表示线程活动的方法,run方法是执行到这个子线程时,自动调用的方法

    start( )              启动线程活动,start方法是声明分到一个子线程的函数已经就绪,等待被CPU执行

    join([time])        设置主线程会等待time秒后再往下执行,time默认为子线程结束,多个子线程之间设置的值会叠加.

    isAlive( )           返回线程是活动线程

    getName( )       返回线程名

    setName( )       设置线程名

    threading.currentThread(): 返回当前执行的线程.

    threading.enumerate(): 返回正在运行的所有线程(list)

    threading.activeCount(): 返回正在运行的线程数量

    单线程执行func1和func2:

            总计用时11秒多.

     多线程执行func1和func2:

            总计用时:6秒多

            此处必须要join()方法让主线程等待所有子线程都运行结束,否则主线程运行结束了,子线程还在

            运行.

     线程安全---多线程共享全局变量:

    多线程之间修改全局变量

            线程之间是共用同一内存的,那么线程可以共享全局变量

            如:2个线程A,B同时对全局变量count递增,A在修改变量count时,刚获取到资源count,还没来得及修改count的值,CPU就被B线程剥夺,此时B读到的count值是A修改之前的值,假如B将count值从100增加到1000,此时CPU再次被A拿到,此时A继续执行之前未修改的count任务,获取到的count值仍是100,假如A将count值从A线程中的100增加到500,B又拿到CPU调度几乎,此时B读到的count数又变成了500,而非之前修改后的1000,此类问题即为多线程情况下的线程安全问题.

            如何解决此类问题?控制线程,避免同时获取数据.

                    同步&互斥锁.

            同步:同步就是协同步调,按照预定的先后顺序进行运行."同"字从字面上容易理解为一起动作,其实不是,"同"字应指协同/协助/互相配合,如进程,线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B执行,再将结果给A,A再继续执行.

            互斥锁:线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁.

                  互斥锁为资源引入的一个状态:锁定/非锁定.

                  某个线程要更改共享数据时,先将其锁定,此时自愿的状态为"锁定",其他线程不能更

                  改直到该线程释放资源,将资源的状态改为"非锁定",其他线程才能再次锁定该资源.

                   互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性.

    threading模块中定义了Lock类,可以方便地处理锁定:

            #创建锁:

    mutex=threading.Lock()

            #锁定:上锁原则---->哪里需要锁,锁就上哪里

    mutex.acquire()

            #释放:

    mutex.release()

    注意:如果这个锁之前是没有上锁的,那么acquire不会堵塞.

    线程安全问题示例:

     解决方案示例:加锁

    GIL全局解释器锁:

            IO密集型:涉及到网络收发,磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗少,任务的大部分时间都在等IO操作完成(IO速度远小于CPU和内存的速度)。

            CPU密集型:即计算密集型,任务的特点是要进行大量的计算,消耗CPU资源,比如计算数据,对视频进行高清解码等,全靠CPU的运算能力。

            GIL锁:即全局解释器锁,每个线程在执行前都要先获得GIL锁才能执行,保证了同一时刻只有1个线程可以执行代码,只能在1个CPU中执行,也就造成无法使用多核CPU的硬件优势;GIL锁锁Cpython解释器造成的,也只存在于cpython类型的解释器中,q其他类型的解释器如Jpython解释器无GIL锁的问题,所以 GIL锁跟python语言本身无任何关系。

    展开全文
  • 针对数据挖掘中经典的Apriori算法在计算频繁项目集时需消耗大量的时间缺点,文中利用多线程并行计算的特点,提出了基于线程并行计算的Apriori算法,该算法是将统计候选项目个数的任务交给多线程来执行,从而达到减少...
  • ,在对程序进行并行化时,为了...为了有效地对这些程序进行并行化,提出了一种基于数据结构的线程划分方法与执行模型。在这种方法 中,程序中的对象被划分成多个组,同一组中对象上的操作被分派到同一个线程中去执行
  • java多线程并行处理List集合数据

    千次阅读 2021-03-24 12:45:51
    前言碎语最近可能要批量处理一些数据,准备使用多线程来助力,回顾了下多线程的一些开发技巧,下面是多线程并行处理List的一个小例子代码看关键/*** @author kl by 2016/6/25* @boke www.kailing.pub*/public class ...

    前言碎语

    最近可能要批量处理一些数据,准备使用多线程来助力,回顾了下多线程的一些开发技巧,下面是多线程并行处理List的一个小例子

    代码看关键

    /**

    * @author kl by 2016/6/25

    * @boke www.kailing.pub

    */

    public class MutilThreadTask {

    public static void main(String[] args) {

    List list = new ArrayList();

    for (int i = 0; i < 8014; i++) {

    list.add(i + "test.png");

    }

    new MutilThreadTask().handleListMutiSchedule(list,5);

    }

    //多线程并行处理list数据集

    public void handleListMutiSchedule(List list,int taskCount){

    System.out.println("begin====================================");

    ScheduledExecutorService executorService= Executors.newScheduledThreadPool(taskCount);

    int start = 0;

    int listSize=list.size();

    int remainder=listSize%taskCount;

    int taskDataSize = listSize/taskCount;

    //平均分配task任务

    for(int i=0;i

    int end = start + taskDataSize;

    //最后如果有分配不均的,多余部分交给最后一个任务处理

    if(i==taskCount-1){

    if(remainder!=0){

    end=listSize;

    }

    }

    executorService.schedule(new Task(list,start,end),0,TimeUnit.SECONDS);

    }

    }

    //多线程并行处理list数据集

    public void handleListMutiThread(List list,int taskCount){

    int start = 0;

    ExecutorService ex = Executors.newFixedThreadPool(taskCount);

    int listSize=list.size();

    int remainder=listSize%taskCount;

    int taskDataSize = listSize/taskCount;

    List futures = new ArrayList(taskCount);

    //平均分配task任务

    for(int i=0;i

    int end = start + taskDataSize;

    //最后如果有分配不均的,多余部分交给最后一个任务处理

    if(i==taskCount-1){

    if(remainder!=0){

    end=listSize;

    }

    }

    Future future=ex.submit(new Task(list,start,end)) ;

    futures.add(future);

    }

    try {

    //处理

    for(Future future : futures){

    Object listsf= future.get();

    }

    System.exit(0);

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    /**

    * Task任务执行单元

    */

    private class Task implements Callable> {

    private List list;

    private int start;

    private int end;

    public Task(List list,int start,int end){

    this.list = list;

    this.start = start;

    this.end = end;

    }

    @Override

    public List call() throws Exception {

    Object obj = null;

    List retList = new ArrayList();

    for(int i=start;i

    obj = list.get(i);

    Thread.sleep(10);//

    System.out.println(Thread.currentThread()+"当前处理:"+obj);

    // System.out.println(UfileUtil.uploadUFile(obj.toString(),new FileInputStream("E:\\test.png")));

    }

    //返回处理结果

    return retList;

    }

    }

    }

    展开全文
  • 1、对于大型数组变量,只读不写,变量作用域默认共享,在多线程并行计算的时候会不会有数据竞争的问题? 2、如果我把变量名设为私有,那么是不是每个线程只有数组头地址的副本?而数组元素仍为共享,这时候是否还...
  • 经过了前面章节内容的学习,下面我们一起来实现一个多线程实现求多个数据相加的和。(这里没有用数组实现,原因在于内存分配给数组的不能有太大空间,N受到限制,不好调试。但是与数组实现方式完全一样!) 假设所...

    c++多线程系列

    c++多线程thread操作(一)环境部署

    c++多线程thread操作(二)线程管理

    c++多线程thread操作(三)数据竞争互斥访问

    c++多线程thread操作(四)死锁的问题和解决

    c++多线程thread操作(五)unique_lock加锁

    c++多线程thread操作(六)条件变量的使用

    c++多线程thread操作(七)父进程获取子进程变量的结果

    c++多线程thread操作(八)父线程传递数据给子线程

    c++多线程thread操作(九)可调用方式

    (终)c++多线程thread操作(十)多线程并行实现数据相加的和

    经过了前面章节内容的学习,下面我们一起来实现一个多线程实现求多个数据相加的和。(这里没有用数组实现,原因在于内存分配给数组的不能有太大空间,N受到限制,不好调试。但是与数组实现方式完全一样!)

    假设所要求解的数据长度是N,cpu的核心数是m;

    很容易考虑到应将数据尽可能等分给每个cpu运行,故每个cpu运行的数据是:(K_i,K_j)

    其中:K_i = $\lceil N/m \rceil$ * i, i = 0,1,..,m-1

    $$ K_i=\left\{ \begin{aligned} \lceil N/m \rceil * i, i=0,1,...,m-2\\ N-1 , i = m-1 \\ \end{aligned} \right. $$

    其实现代码如下:这里实现获取子线程结果的方式是加入的引用变量;(可以用future变量,很可惜就是不能提速)

    #include <iostream>
    #include <thread>
    using namespace std;
    const int N = 2000000000;
    void func_2(int begin, int end, int &res) {
    	res = 0;
    	int sum = 0;
    	for (int kk = 1; kk < 10; kk++)
                for (int i = begin; i < end; i++) {
    		    sum = (sum + i + 1);
    	}
    	res = sum;
    }
    int multi_thread() {
    	int cpu_num = thread::hardware_concurrency();//12
    	int use_cpu_num = cpu_num;
    	int split_num = (N + use_cpu_num - 1) / use_cpu_num;
    	int k1 = 0, k2 = split_num;// k1,k2切分数组
    	int sum = 0;
    	int *res = new int[split_num];
    	thread *th = new thread[use_cpu_num];
    	for (int i = 0; i < use_cpu_num; i++) {
    		th[i] = thread(func_2, k1, k2, ref(res[i]));
    		k1 = k2;
    		k2 += split_num;
    		if (k2 >= N)k2 = N;
    	}
    	for (int i = 0; i < use_cpu_num; i++)th[i].join();
    	for (int i = 0; i < use_cpu_num; i++) {
    		sum = (sum + res[i]);
    	}
    	return sum;
    }
    
    int main() {
    	long c1 = clock();
    	int res;
    	func_2(0, N, res);
    	long c2 = clock();
    	cout << "res = " << res << " , time consume = " << c2 - c1 << endl;
    
    	c1 = clock();
    	int sum = multi_thread();
    	c2 = clock();
    	cout << "sum = " << sum << " , time consume = " << c2 - c1 << endl;
    
    	return 0;
    }

    运行结果如下:

    res 是单线程获取结果;sum是多线程获取结果

    Debug模式测试:多线程加速比大约是:800%-900%

    1. cpu=12, kk = 10(第八行);

    2. cpu=12, kk = 15(第八行)

    3. cpu=12, kk = 30(第八行)

    Release测试:多线程加速比大约是:400%-500%

    1. cpu=12, kk = 10(第八行);

    2. cpu=12, kk = 15(第八行)

    3. cpu=12, kk = 30(第八行)

     

    注:

    以上只运行了加法运算,如果运行乘除法,加速比会更高!!

    下面是采用了求余运算。

    void func_2(int begin, int end, int &res) {
    	res = 0;
    	int sum = 0;
    	for (int kk = 1; kk < 10; kk++)
    		for (int i = begin; i < end; i++) {
    			sum += (i + 1)%1000;
    			sum = sum % 1000;
    		}
    	res = sum;
    }

    1. N = 20000000; kk=10

    2. N = 200000000;kk=10

    展开全文
  • 线程并发和并行的区别

    万次阅读 2020-09-13 14:35:34
     随着jdk1.8的普及,多线程处理问题,除了使用使用线程池(ExecutorService),很多人选择了parallelStream() 并行流,底层使用forkjoin实现并行处理。  那么并行和并发又有什么区别?究竟改如何选择?滥用时又会有...
  • Android进程线程间通信方式

    千次阅读 2021-01-17 13:22:41
    进程:是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。线程:是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程...
  • Python--多线程并行

    千次阅读 2020-11-09 08:12:03
    一、线程和进程介绍 ...程序只是指令、数据及其组织形式的描述,进程才是程序(哪些指令和数据)的真正运行实例。 若干进程有可能与同一程序有关系,且每个进程皆可以同步(循序)或异步(平行)的方式独立
  • java实现多线程 并发和并行理解

    千次阅读 2022-03-30 15:57:59
    ➤ java中的Thread类定义了多线程,通过多线程可以实现并发或并行。 ➤ 在CPU比较繁忙,资源不足的时候(开启了很多进程),操作系统只为一个含有多线程的进程分配仅有的CPU资源,这些线程就会为自己尽量多抢时间片...
  • 有这么一个需求,数据库20w数据,如果直接从数据库一次性读取比较慢,怎么用多线程 分批次并行读取,然后将List结果汇总
  • 多态并行处理器中的线程管理器设计.pdf
  • java8 Stream多线程并行数据处理

    千次阅读 2018-11-16 13:13:06
    Stream多线程并行数据处理 将一个顺序执行的流转变成一个并发的流只要调用 parallel()方法 public static long parallelSum(long n){ return Stream.iterate(1L, i -&amp;amp;amp;amp;amp;gt; i +1).limit(n...
  • 节点内利用Cilk任务并行模型解决了线程并行数据依赖和饥饿等待等问题,提高了并行性;节点通过改进合并过程中的通信流程,使组内进程只进行互补的数据交换,降低了通信开销.数值实验体现了该混合并行算法在...
  • 作者:Eureka912 ... 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权...进程(processes)与线程(thread) 我们先说个例子:小明的一天 上午:洗脸刷牙,吃早饭,听音乐 下午: 坐公交到公园玩, 晚上:
  • python_并行与并发、多线程

    千次阅读 2020-12-28 22:27:16
    并行需要的核心条件 多进程实现并行问题一: 什么是进程?计算机程序是存储在磁盘上的文件。只有把它们加载到内存中,并被操作系统调用 它们才会拥有其自己的生命周期。进程表示一个正在执行的程序。每个进程都有...
  • 网络处理器并行性能模型及多线程停顿特性.pdf
  • 使用多线程处理输入的数据

    千次阅读 2021-02-03 21:17:49
    TensorFlow 的 Session 对象是支持多线程的,因此多个线程可以很方便地在同一个会话下对同一个队列并行地执行操作。Python 本身也提供了创建线程的threading.py,这个文件提供了Thread 类来创建线程,Thread 类的 ...
  • 线程和进程一--并发和并行

    千次阅读 2022-03-20 11:25:04
    一、并行和并发 并行,parallel:同一个时间点,不同任务同时进行,互不干扰。 并发,concurrency:需要同时做某些事,强调的是需要处理多项事务,不一定同时进行。 —> 并行解决的是并发需求的一种方式。 —>...
  • Matlab 多线程并行计算

    千次阅读 2020-12-17 21:22:42
    首先要区分一下并行计算与多线程的区别。并行计算是指 开启多核来进行同一个任务的计算。多线程是指调用资源来分别执行多个不同的任务。 Matlab 并行计算是在2012版本之后就从 matlabpool 命令改成了 parpool命令,...
  • 线程并行和并发的理解,当我们开启了多线程以后,多线程执行的任务交给cpu去执行,如果cpu是多核的,此时执行的就是并行(并行在多核上,一个核上运行一个线程),如果是一个核,相当于在cpu里面执行线程也需要...
  • 基于自适应线程束的GPU并行粒子群优化算法.pdf
  • java 文件多线程并行读取

    千次阅读 2022-04-10 15:21:42
    java 文件多线程并行读取
  • kafka Consumer 多线程并行消费数据

    千次阅读 2019-08-20 17:17:45
    kafka Consumer 多线程并行消费数据 : https://blog.csdn.net/qq_31289187/article/details/81983017
  • 基于多线程多GPU并行加速的最小二乘逆时偏移算法.pdf
  • 基于多态并行处理器提出了一种硬件线程管理器,支持MIMD模式8个线程...能够在通信时停止、切换、启动线程,记录每个线程的工作状态,同时避免了因数据阻塞带来的等待问题,能够最大程度地提高单个处理器的执行效率。
  • 将一个顺序执行的流转变成一个并发的流只要调用parallel()方法 publicstaticlongparallelSum(longn){ returnStream.iterate(1L,i->...并行流就是一个把内容分成多个数据块,并用不不同的线程分别处理...
  • java8------Stream多线程并行数据处理

    千次阅读 2019-02-16 10:17:16
    java8推出steam流概念,像管道一样,将数据比作液体,在管道...1.串行流与并行流在数据量不大的前提下,串行处理的效率要比并行操作高.只有在较大数据前提下,才能显现并行的优势. 2.在对有顺序依赖的操作,如limit,fi...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 273,969
精华内容 109,587
热门标签
关键字:

并行线程间的数据问题