• java并发计算的几种基本使用示例


    通常我们使用程序处理计算,常见的有单线程,JUC下单的多线程,还有优秀的ForkJoin框架(与递归形式上相似却又优于递归),直接上代码吧

     1 package com.fork;
     2 
     3 import java.util.concurrent.ExecutionException;
     4 import java.util.concurrent.ForkJoinPool;
     5 import java.util.concurrent.ForkJoinTask;
     6 import java.util.concurrent.RecursiveTask;
     7 10 
    11 public class ForkDemo extends RecursiveTask<Long>{
    12     private long end;
    13     private final long THRELOD = 500000000L;
    14     private  long start;
    15     public ForkDemo(long start ,long end) {
    16         this.end = end;
    17         this.start = start;
    18     }
    19 
    20     @Override
    21     protected  Long compute() {
    22         long v = 0;
    23         if( end - start <= THRELOD) {
    24             for (long i = start; i <= end; i++) {
    25                 v += i;
    26             }
    27             return v;
    28         }else {
    29             long middle = (end + start)/2;
    30             ForkDemo demo1 = new ForkDemo(start, middle);
    31             ForkDemo demo2 = new ForkDemo(middle+1, end);
    32             demo1.fork();
    33              demo2.fork();
    34             return demo1.join() + demo2.join();
    35             
    36         }        
    37     }
    38 }

     这是ForkJoin的基本示例使用,以下是三种计算的比较;

    package com.fork;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ForkJoinPool;
    import java.util.concurrent.ForkJoinTask;
    import java.util.concurrent.Future;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    
    
    
    public class LockDemo {
    //	 单线程方式
    	public static long execSingle(long n) {
    		long sum = 0;
    		for (long i = 1; i <= n; i++) {
    			sum += i;
    		}
    		System.out.println("the sum = " + sum);
    		return sum;
    	}
    //	 多线程方式
    	 public static long execMult(long n) throws ExecutionException {
    		 long value = 0L;
    	     ExecutorService exect = Executors.newFixedThreadPool(3);
    	     ArrayList<Callable<Long>> list =new ArrayList<Callable<Long>>();
    	     long total;
    	     list.add(()->{
    	        long sum = 0L;
    	    	for(Long i=1L;i<=n;i+=3) {
    	    		sum += i;
    	    	}
    	    	return sum;
    	    });
    	     list.add(()->{
    		        long sum = 0L;
    		    	for(Long i=2L;i<=n;i+=3) {
    		    		sum += i;
    		    	}
    		    	return sum;
    		    });
    	     list.add(()->{
    		        long sum = 0L;
    		    	for(Long i=3L;i<=n;i+=3) {
    		    		sum += i;
    		    	}
    		    	return sum;
    		    });
    	   List<Future<Long>> end =null;
    	     try {
    			end = exect.invokeAll(list);
    			for(Future<Long> t:end) {
    				value += t.get();
    			}
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	     exect.shutdownNow();
    	     System.out.println("this end is " + value);
    	     return value;  
    	 }
    	 
    
    	 public static void main(String[] args) throws ExecutionException {
    		 Long start1 =  System.currentTimeMillis();
    		 execSingle(3800000000L);
    		 Long end1 =  System.currentTimeMillis();
    		 System.out.println("单线程下:end1 - start1 = " +(end1-start1) );
    		 Long start2 =  System.currentTimeMillis();
    		 execMult(3800000000L);
    		 Long end2 =  System.currentTimeMillis();
    		 System.out.println("多线程下:end2 - start2 = " +(end2-start2) );
    		 Long start3 =  System.currentTimeMillis();
    		 ForkJoinPool pool = new ForkJoinPool();
    		 ForkDemo demo = new ForkDemo(0L, 3800000000L);
    		 ForkJoinTask<Long> task = pool.submit(demo);
    		 Long end3 =  System.currentTimeMillis();
    		 System.out.println("forkjoin框架下:end3 - start3 = " +(end3-start3) );
    		 try {
    			System.out.println(task.get());
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		 
    	}
    }
    

      最后控制台输出:(ForkJoin 优秀啊.....此处向大神Doug Lea模拜......)

    注意ForkJoin需要使用合理的细分程度,这里多线程计算时间夸张了点.....具体情境还是要具体分析,有些情况多线程不一定比多线程快(有线程切换的代价),多线程需要互不依赖,如爬取图片,以此我也不知道....多线程花了这么多时间,哪位大佬给分下.....

    好好生活,天天向上
  • 相关阅读:
    Linux | Ubuntu 生成二维码实例
    Ubuntu 添加wine安装程序的快捷方式
    mysql 中文 排序
    Received disconnect from **.**).***.*** port 22:2: Too many authentication failures 解决办法
    php 数组与URL相互转换
    ssh `快捷键` 快速链接服务器
    使用ssh生成密钥并保存在不同的文件(ubuntu)
    H5移动端调试 weinre
    简单的 图片下载 php
    linux 系统生成二维码
  • 原文地址:https://www.cnblogs.com/linchongatfirst/p/10975122.html
Copyright © 2020-2023  润新知