多线程并发快速处理数据

方案一:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class LargSumWithCallable {

	static int threadCounts =10;//使用的线程数
	static long sum=0; 

  public static void main(String []args) throws InterruptedException, ExecutionException{

    ExecutorService exec=Executors.newFixedThreadPool(threadCounts);
    List<Callable<Long>> callList=new ArrayList<Callable<Long>>();  

    List<Integer> list = new ArrayList<Integer>();

    for (int j = 0; j <= 1000000;j++)  {
        list.add(j);
    }

    int len=list.size()/threadCounts;//平均分割List
    //List中的数量没有线程数多(很少存在)
    if(len==0){
        threadCounts=list.size();//采用一个线程处理List中的一个元素
        len=list.size()/threadCounts;//重新平均分割List
    }
    for(int i=0;i<threadCounts;i++){
        final List<Integer> subList;
        if(i==threadCounts-1){
            subList=list.subList(i*len,list.size());
        }else{
            subList=list.subList(i*len, len*(i+1)>list.size()?list.size():len*(i+1));
        }
        //采用匿名内部类实现
        callList.add(new Callable<Long>(){
            public Long call() throws Exception {
                long subSum=0L;
                for(Integer i:subList){
                    subSum+=i;
                }
                System.out.println("分配给线程:"+Thread.currentThread().getName()+"那一部分List的整数和为:\tSubSum:"+subSum);
                return subSum;
            }
        });
    }
    List<Future<Long>> futureList=exec.invokeAll(callList);
    for(Future<Long> future:futureList){
        sum+=future.get();
    }
    exec.shutdown();
    System.out.println(sum);
  }
 }

方案二:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class LargeListIntegerSum {

	    private long sum;//存放整数的和
	    private CyclicBarrier barrier;//障栅集合点(同步器)
	    private List<Integer> list;//整数集合List
	    private int threadCounts;//使用的线程数
	    public LargeListIntegerSum(List<Integer> list,int threadCounts) {
	        this.list=list;
	        this.threadCounts=threadCounts;
	    }
	    /**
	     * 获取List中所有整数的和
	     * @return
	     */
	    public long getIntegerSum(){
	        ExecutorService exec=Executors.newFixedThreadPool(threadCounts);
	        int len=list.size()/threadCounts;//平均分割List
	        //List中的数量没有线程数多(很少存在)
	        if(len==0){
	            threadCounts=list.size();//采用一个线程处理List中的一个元素
	            len=list.size()/threadCounts;//重新平均分割List
	        }
	        barrier=new CyclicBarrier(threadCounts+1);
	        for(int i=0;i<threadCounts;i++){
	            //创建线程任务
	            if(i==threadCounts-1){//最后一个线程承担剩下的所有元素的计算
	                exec.execute(new SubIntegerSumTask(list.subList(i*len,list.size())));
	            }else{
	                exec.execute(new SubIntegerSumTask(list.subList(i*len, len*(i+1)>list.size()?list.size():len*(i+1))));
	            }
	        }
	        try {
	            barrier.await();//关键,使该线程在障栅处等待,直到所有的线程都到达障栅处
	        } catch (InterruptedException e) {
	            System.out.println(Thread.currentThread().getName()+":Interrupted");
	        } catch (BrokenBarrierException e) {
	            System.out.println(Thread.currentThread().getName()+":BrokenBarrier");
	        }
	        exec.shutdown();
	        return sum;
	    }
	    /**
	     * 分割计算List整数和的线程任务 

	     *
	     */
	    public class SubIntegerSumTask implements Runnable{
	        private List<Integer> subList;
	        public SubIntegerSumTask(List<Integer> subList) {
	            this.subList=subList;
	        }
	        public void run() {
	            long subSum=0L;
	            for (Integer i : subList) {
	                subSum += i;
	            }
	            synchronized(LargeListIntegerSum.this){//在LargeListIntegerSum对象上同步
	                sum+=subSum;
	            }
	            try {
	                barrier.await();//关键,使该线程在障栅处等待,直到所有的线程都到达障栅处
	            } catch (InterruptedException e) {
	                System.out.println(Thread.currentThread().getName()+":Interrupted");
	            } catch (BrokenBarrierException e) {
	                System.out.println(Thread.currentThread().getName()+":BrokenBarrier");
	            }
	            System.out.println("分配给线程:"+Thread.currentThread().getName()+"那一部分List的整数和为:\tSubSum:"+subSum);
	        }  

	    }  

	    public static void main(String[] args) {
	        List<Integer> list = new ArrayList<Integer>();
	        int threadCounts = 10;//采用的线程数  

	        for (int i = 1; i <= 1000000; i++) {
	            list.add(i);
	        }  

	        long start=  System.currentTimeMillis();
	        LargeListIntegerSum countListIntegerSum=new LargeListIntegerSum(list,threadCounts); 

	        long sum=countListIntegerSum.getIntegerSum();
	        System.out.println("List中所有整数的和为:"+sum);
	        long end=  System.currentTimeMillis();
	        System.out.println(end-start);
	    }  

}
时间: 2024-10-13 21:23:36

多线程并发快速处理数据的相关文章

Java多线程并发基础面试题回答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含了不同的类和程序的单一进程.线程可以被称为轻量级进程.线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源. 2. 多线程编程的好处是什么? 在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态.多个线程共享堆内存(heap

互联网架构多线程并发编程高级教程(上)

#基础篇幅:线程基础知识.并发安全性.JDK锁相关知识.线程间的通讯机制.JDK提供的原子类.并发容器.线程池相关知识点? #高级篇幅:ReentrantLock源码分析.对比两者源码,更加深入理解读写锁,JAVA内存模型.先行发生原则.指令重排序?#环境说明:idea.java8.maven #第一章 并发简介 ?? ?##01 课程简介 ?? ??? ?为什么要学习并发编程? ?? ??? ??? ?方便实际开发 ?? ??? ??? ??? ?面试 ?? ??? ??? ??? ?课程特点

架构师必备之面试题整理——多线程并发技术要点!

一.概念 什么是线程 一个线程要执行任务,必须得有线程 一个进程(程序)的所有任务都在线程中执行的 一个线程执行任务是串行的,也就是说一个线程,同一时间内,只能执行一个任务 多线程原理 同一时间,CPU只能处理1条线程,只有一条线程在工作(执行) 多线程并发(同时)执行,其实质是CPU快速的在多线程之间调度(切换) 如果线程过多,会怎样? CPU在N多条线程中调度,会消耗大量的cpu资源 每条线程被调度执行的频率越低(线程的执行效率低) 多线程的优点 能适当提高程序的执行效率 能适当提高资源的利

Cocos2d-x优化中多线程并发访问

多线程并发访问在Cocos2d-x引擎中用的不是很多,这主要是因为中整个结构设计没有采用多线程.源自于Objective-C的Ref对象,需要使用AutoreleasePool进行内存管理,AutoreleasePool是非线程安全的,所有不推荐在子多线程中调用Ref对象的retain(). release()和autorelease()等函数.另外,OpenGL上下文对象也是不支持线程安全的.但是有的时候我们需要异步加载一些资源,例如:加载图片纹理.声音的预处理和网络请求数据等.如果是异步加载

iOS Core data多线程并发访问的问题

大家都知道Core data本身并不是一个并发安全的架构:不过针对多线程访问带来的问题,Apple给出了很多指导:同时很多第三方的开发者也贡献了很多解决方法.不过最近碰到的一个问题很奇怪,觉得有一定的特殊性,与大家分享一下. 这个问题似乎在7.0.1以前的版本上并不存在:不过后来我升级版本到了7.0.4.app的模型很简单,主线程在前台对数据库进行读写,而后台线程不断地做扫描(只读).为此每个线程中各创建了一个NSManagedObjectContext. 这个模型其实有点奇怪,因为普遍的模型是

使用Chrome快速实现数据的抓取(四)——优点

些一个抓取WEB页面的数据程序比较简单,大多数语言都有相应的HTTP库,一个简单的请求响应即可,程序发送Http请求给Web服务器,服务器返回HTML文件.交互方式如下: 在使用DevProtocol驱动Chrome抓取数据时,交互过程则如下图所示: 此时Chrome在中间充当了一个代理的角色,看上去变得更加复杂了,实际上却对于我们的蜘蛛程序大有帮助.本文就简单的总结下这种方式存在如下优点. 获取动态生成的网页内容 现在很多的网页内容的内容并不是一开是就能直接通过最初的Http请求直接获取到的,

代码就支持了多线程并发

100行代码就支持了多线程并发,批量写入日志 一,您选择用什么样的日志组件 日志组件,不得不提大名鼎鼎的Log4Net.比较常用的还有 Enterprise Library Logging,ServiceStack Logging.当然您还可以补充,我就只用过这几款. 上边提到的3款日志组件,都要在.config里加代码,特别是Log4Net,还要把SQL写在配置里.我就是仅仅只写个日志,还要配置这么多信息,让人略有不爽. 所以在很长一段时间里,我用下边这个方法写日志:   这个方法足够的简单,

解决多线程并发问题

1.文件锁 如果对该表的更新或插入的操作,都会经过一个统一的文件,这种方式是可以解决的多进程并发的问题: 实现方式如下: public static function cbInventoryReserve() { $LOCK_FILE_PATH = $_SERVER['DOCUMENT_ROOT']."wmsinventoryapi/inventory/InventoryReserve.php"; $fp = fopen( $LOCK_FILE_PATH, "r"

多线程并发编程

前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们来说极其重要,下面跟我一起开启本次的学习之旅吧. 正文 线程与进程 1 线程:进程中负责程序执行的执行单元线程本身依靠程序进行运行线程是程序中的顺序控制流,只能使用分配给程序的资源和环境 2 进程:执行中的程序一个进程至少包含一个线程 3 单线程:程序中只存在一个线程,实际上主方法就是一个主线程 4 多线程:在一个程序中运行多个任务目的是更好地使用CPU资源 线程的实现 继承Thread类 在j