精华内容
下载资源
问答
  • 题目:一个主线程有多个子线程任务,主线程必须在100秒内将子线程执行的集合结果进行处理返回,子线程如果在100秒内没有执行完停止执行。写了3个例子,用Future、FutureTask、ThreadPoolExecutor...
    个人记录:2018年,工作的第6到7个年头。
    重点研究自己不太擅长的技术:分布式、高并发、大数据量、数据库优化、高性能、负载均衡等。
    刷题是一种态度,是一种好习惯。
    我刷题,我骄傲。


    题目:一个主线程下有多个子线程任务,主线程必须在100秒内将子线程执行的集合结果进行处理返回,子线程如果在100秒内没有执行完停止执行。




    写了3个例子,用Future、FutureTask、ThreadPoolExecutor、CompletionService。




    例子1:
    package cn.fansunion.executorservice;
    
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    
    //获得Future的值,如果还没返回,就等待
    public class FutureTaskTest {
    
    
    	public static void main(String[] args) {
    		// 【强制】线程池不允许使用 Executors ExecutorsExecutors
    		// 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor
    		// ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。
    		int nThreads = 5;
    		ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
    				new LinkedBlockingQueue<Runnable>(1000));
    		List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(10);
    		for (int index = 1; index <= 10; index++) {
    			Integer num = new Random().nextInt(10);
    			System.out.println(String.format("index:%s,num=%s", index,num));
    			FutureTask<Integer> task = new FutureTask<>(new Callable<Integer>() {
    
    
    				public Integer call() throws Exception {
    					int maxSleepNum = 10;
    					Integer sleepNum = new Random().nextInt(maxSleepNum);
    					System.out.println(String.format("SleepNum:%s", sleepNum));
    					Thread.sleep(sleepNum*1000);
    					return num;
    				}
    
    
    			});
    			if(!executor.isShutdown()){
    				executor.submit(task);
    			}
    			taskList.add(task);
    		}
    		Integer sum = 0;
    		for (FutureTask<Integer> task : taskList) {
    			try {
    				//阻塞,Waits if necessary for the computation to complete, and then retrieves its result.
    				Integer num = task.get();
    				System.out.println(String.format("num=%s",num));
    				sum += num;
    			} catch (InterruptedException | ExecutionException e) {
    				e.printStackTrace();
    			}
    
    
    		}
    		executor.shutdownNow();
    		System.out.println(sum);
    	}
    
    
    }






    例子2:
    package cn.fansunion.executorservice;
    
    
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.Future;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    /**
     * CompletionService,先获得,最快得到结果的那个线程的值
     * @author leiwen1
     *
     */
    public class FutureTaskTest2 {
    
    
    	public static void main(String[] args) {
    		// 【强制】线程池不允许使用 Executors ExecutorsExecutors
    		// 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor
    		// ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。
    		int nThreads = 5;
    		ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
    				new LinkedBlockingQueue<Runnable>(1000));
    		CompletionService<Integer> completionService= new ExecutorCompletionService<Integer>(executor);
    		int maxIndex = 10;
    		//List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(maxIndex);
    		for (int index = 1; index <= maxIndex; index++) {
    			Integer num = new Random().nextInt(maxIndex);
    			System.out.println(String.format("index:%s,num=%s", index,num));
    			Callable<Integer> callable = new Callable<Integer>() {
    
    
    				public Integer call() throws Exception {
    					int maxSleepNum = 10;
    					Integer sleepNum = new Random().nextInt(maxSleepNum);
    					System.out.println(String.format("SleepNum:%s", sleepNum));
    					Thread.sleep(sleepNum*1000);
    					return num;
    				}
    
    
    			};
    			//Future<Integer> task = new FutureTask<>(callable);
    			if(!executor.isShutdown()){
    				completionService.submit(callable);
    			}
    		}
    		Integer sum = 0;
    		for (int index = 1; index <= maxIndex; index++) {
    			try {
    				//查询最新1个完成的任务,然后删除
    				//Retrieves and removes the Future representing the next completed task, waiting if none are yet present.
    				Future<Integer> future = completionService.take();
    				Integer num = future.get();
    				System.out.println(String.format("num=%s",num));
    				sum += num;
    			} catch (InterruptedException | ExecutionException e) {
    				e.printStackTrace();
    			}
    
    
    		}
    		executor.shutdownNow();
    		System.out.println(sum);
    	}
    
    
    }






    在例子2的基础上,改了点,就是题目所要的效果。
    例子3:
    package cn.fansunion.executorservice;
    
    
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.Future;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    /**
     * CompletionService,先获得,最快得到结果的那个线程的值
     * pool方法,可以设置超时时间
     *
     */
    public class FutureTaskTest3 {
    
    
    	public static void main(String[] args) {
    		// 【强制】线程池不允许使用 Executors ExecutorsExecutors
    		// 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor
    		// ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。
    		int nThreads = 5;
    		ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
    				new LinkedBlockingQueue<Runnable>(1000));
    		CompletionService<Integer> completionService= new ExecutorCompletionService<Integer>(executor);
    		int maxIndex = 100;
    		//1到100求和
    		for (int index = 1; index <= maxIndex; index++) {
    			Integer num = index;
    			System.out.println(String.format("index:%s,num=%s", index,num));
    			Callable<Integer> callable = new Callable<Integer>() {
    
    
    				public Integer call() throws Exception {
    					//让一部分超时
    					int maxSleepNum = 350;
    					Integer sleepNum = new Random().nextInt(maxSleepNum);
    					System.out.println(String.format("SleepNum:%s", sleepNum));
    					//模拟计算时间,比如从远程查询数据
    					Thread.sleep(sleepNum);
    					return num;
    				}
    
    
    			};
    			//Future<Integer> task = new FutureTask<>(callable);
    			if(!executor.isShutdown()){
    				completionService.submit(callable);
    			}
    		}
    		//所有成功返回的num
    		Integer[] taskNumArray = new Integer[maxIndex];
    		for (int index = 1; index <= maxIndex; index++) {
    			try {
    				//等待下1个完成的任务,然后删除,但是最多等待一定的时间
    				Future<Integer> future = completionService.poll(100, TimeUnit.MILLISECONDS);
    				//模拟100毫秒,方便模拟超时,程序快点执行
    				if(future==null){
    					break;
    				}
    				Integer num = future.get();
    				taskNumArray[index-1]=num;
    				System.out.println(String.format("num=%s,成功返回1个数据",num));
    			} catch (InterruptedException | ExecutionException e) {
    				e.printStackTrace();
    			}
    
    
    		}	
    		executor.shutdownNow();
    		Integer sum = 0;
    		//Collections.sort(Arrays.asList(taskNumArray));
    		//System.out.println(taskNumArray);
    		for(Integer num:taskNumArray){
    			//超时的那几个,么有值,位置是空的
    			if(num != null){
    				System.out.print(num+",");
    				sum+= num;
    			}
    		}
    		System.out.println();
    		System.out.println(String.format("sum=%s", sum));
    	}
    
    
    }




    输出结果(每次都是随机的):
    num=53,成功返回1个数据
    SleepNum:1
    num=56,成功返回1个数据
    SleepNum:296
    num=61,成功返回1个数据
    1,5,3,6,2,4,8,11,7,14,10,13,17,15,9,19,16,22,12,20,23,24,25,18,21,26,30,27,29,28,33,35,31,37,34,38,40,32,42,39,36,45,46,48,41,43,50,49,47,52,44,55,51,54,53,56,61,
    sum=1657

    展开全文
  • 个主线程有多个子线程任务,主线程必须在100秒内将子线程执行的集合结果进行处理返回 实现代码: package cmd.chengxuyuanzhilu.async; import java.util.ArrayList; import java.util.List; import ...

    一个主线程下有多个子线程任务,主线程必须在100秒内将子线程执行的集合结果进行处理返回

    实现代码:

    package cmd.chengxuyuanzhilu.async;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author 微信公众号:程序员之路
     *
     */
    class Task implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println(String.format("子线程 %s: 在进行计算", Thread.currentThread().getName()));
            Thread.sleep(6000);
            int sum = 0;
            for (int i = 0; i < 100; i++)
                sum += i;
            return "子进程"+Thread.currentThread().getName()+":"+sum;
        }
    }
    
    /**
     * @author 微信公众号:程序员之路
     *
     */
    public class Test {
        public static void main(String[] args) {
            //个人建议,控制线程池中线程的个数,防止开启过多线程造成系统崩溃
            ExecutorService executor = Executors.newFixedThreadPool(5);
            
            //创建100个任务
            List<Task> tasks = new ArrayList<>();
            for (int i = 0; i < 100; i++) {
                Task task = new Task();
                tasks.add(task);
            }
            
            //ExecutorService的invokeAll方法执行任务集合中的所有任务,并设置超时时间(100秒)。超时后的任务将取消进行
            List<Future<String>> futures = new ArrayList<>();
            try {
                futures = executor.invokeAll(tasks, 100, TimeUnit.SECONDS);//注:执行所有的方法执行完的时间不能超过100秒,超时后的任务将取消执行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            executor.shutdown();
            
            Integer i = 1;
            Integer j = 0;
            for (Future<String> future : futures) {
                try {
                    System.out.println(i+" : "+future.get());
                    i++;
                }catch (Exception e) {
                    j++;
                } 
            }
            System.out.println("未成功执行的任务个数:"+j);
        }
    }

     

    转载于:https://www.cnblogs.com/chengxuyuanzhilu/p/5796363.html

    展开全文
  • 现在情况是,主线程会不时的创建子线程,有些子线程很快退出,的会运行一段时间再退出,的会一直运行,只有主线程通知后才会退出。无法事先预知到主线程会创建多少、什么样的线程。 . 主线程退出之前会发出...
  • 比如网络请求,分别在两子线程里执行,得到数据后存在数据库里。主线程里需要用到他们执行后的数据,从数据库里读取。 这时候就会出现一问题,如果在请求后立马读取数据,是读不到的,因为子线程里的...

    比如有两个网络请求,分别在两个子线程里执行,得到数据后存在数据库里。主线程里需要用到他们执行后的数据,从数据库里读取。

    这个时候就会出现一个问题,如果在请求后立马读取数据,是读不到的,因为子线程里的网络请求是耗时操作。

    解决方法:主线程里开子线程前,写上final CountDownLatch latch = new CountDownLatch(2);//几个子线程就写几,然后在每个子线程结束末尾写上latch.countDown();在子线程执行完之后,写上:latch.await();这个需要try/catch。这个时候就可以保证子线程全部执行完了。


    19年6月4日补充:

    之前的方法固然简单,但是存在线程阻塞的问题。这在某些 地方是坚决不能出现的,轻则界面动画卡顿,重则程序崩溃。所以,开发时应避免使用CountDownLatch

    在安卓,通常使用Handler去处理。设计一个等待子线程,里面就一个while循环。当然,如果考虑到特殊情况,设置一个时间,超时就跳出。每个子线程执行完毕,用Message通知主线程将一个记号变量加一。当子线程都执行完,所有的数据都拿到后,通过判断记号打破while循环,也就是等待子线程里写的Message,它通知主线程做最终的处理信息的操作。

    展开全文
  • 写了3例子,用Future、FutureTask、ThreadPoolExecutor、CompletionService。例子1: package cn.fansunion.executorservice; import java.util.ArrayList; import java.util.List; import java.util.Random;...

    写了3个例子,用Future、FutureTask、ThreadPoolExecutor、CompletionService。

    例子1:

     

    package cn.fansunion.executorservice; 

     

     

    import java.util.ArrayList; 

    import java.util.List; 

    import java.util.Random; 

    import java.util.concurrent.Callable;

    import java.util.concurrent.ExecutionException; 

    import java.util.concurrent.FutureTask; 

    import java.util.concurrent.LinkedBlockingQueue;

    import java.util.concurrent.ThreadPoolExecutor; 

    import java.util.concurrent.TimeUnit; 

     

     

    //获得Future的值,如果还没返回,就等待 

    public class FutureTaskTest { 

     

     

        public static void main(String[] args) { 

            // 【强制】线程池不允许使用 Executors ExecutorsExecutors 

            // 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor 

            // ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。 

           int nThreads = 5

            ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, 

                    new LinkedBlockingQueue<Runnable>(1000)); 

            List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(10); 

            for (int index = 1; index <= 10; index++) { 

                Integer num = new Random().nextInt(10); 

               System.out.println(String.format("index:%s,num=%s", index,num)); 

                FutureTask<Integer> task = new FutureTask<>(new Callable<Integer>() { 

     

     

                    public Integer call() throws Exception { 

                        int maxSleepNum = 10

                        Integer sleepNum = new Random().nextInt(maxSleepNum); 

                        System.out.println(String.format("SleepNum:%s", sleepNum)); 

                        Thread.sleep(sleepNum*1000); 

                        return num; 

    }

    例子2:

     

    package cn.fansunion.executorservice; 

     

     

    import java.util.Random; 

    import java.util.concurrent.Callable;

    import java.util.concurrent.CompletionService; 

    import java.util.concurrent.ExecutionException;

    import java.util.concurrent.ExecutorCompletionService; 

    import java.util.concurrent.Future; 

    import java.util.concurrent.LinkedBlockingQueue; 

    import java.util.concurrent.ThreadPoolExecutor; 

    import java.util.concurrent.TimeUnit; 

    /**

    * CompletionService,先获得,最快得到结果的那个线程的值

    * @author leiwen1

    *

    */ 

    public class FutureTaskTest2 { 

        public static void main(String[] args) { 

            // 【强制】线程池不允许使用 Executors ExecutorsExecutors 

            // 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor 

            // ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。 

            int nThreads = 5

            ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, 

                    new LinkedBlockingQueue<Runnable>(1000)); 

            CompletionService<Integer> completionService= new ExecutorCompletionService<Integer>(executor); 

            int maxIndex = 10

           //List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(maxIndex); 

           for (int index = 1; index <= maxIndex; index++) { 

                Integer num = new Random().nextInt(maxIndex); 

                System.out.println(String.format("index:%s,num=%s", index,num)); 

                Callable<Integer> callable = new Callable<Integer>() { 

     

                   public Integer call() throws Exception { 

                        int maxSleepNum = 10

                        Integer sleepNum = new Random().nextInt(maxSleepNum); 

                        System.out.println(String.format("SleepNum:%s", sleepNum)); 

                        Thread.sleep(sleepNum*1000); 

                        return num; 

                    } 

                }; 

                //Future<Integer> task = new FutureTask<>(callable); 

                if(!executor.isShutdown()){ 

                    completionService.submit(callable); 

                } 

            } 

           Integer sum = 0

            for (int index = 1; index <= maxIndex; index++) { 

                try

                    //查询最新1个完成的任务,然后删除 

                    //Retrieves and removes the Future representing the next completed task, waiting if none are yet present. 

                    Future<Integer> future = completionService.take(); 

                    Integer num = future.get(); 

                    System.out.println(String.format("num=%s",num)); 

                    sum += num; 

                } catch (InterruptedException | ExecutionException e) { 

                    e.printStackTrace(); 

                }

     

            } 

            executor.shutdownNow(); 

            System.out.println(sum); 

        } 

     

    package cn.fansunion.executorservice;
    
    
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.Future;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    /**
     * CompletionService,先获得,最快得到结果的那个线程的值
     * @author leiwen1
     *
     */
    public class FutureTaskTest2 {
    
    
    	public static void main(String[] args) {
    		// 【强制】线程池不允许使用 Executors ExecutorsExecutors
    		// 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor
    		// ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。
    		int nThreads = 5;
    		ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
    				new LinkedBlockingQueue<Runnable>(1000));
    		CompletionService<Integer> completionService= new ExecutorCompletionService<Integer>(executor);
    		int maxIndex = 10;
    		//List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>(maxIndex);
    		for (int index = 1; index <= maxIndex; index++) {
    			Integer num = new Random().nextInt(maxIndex);
    			System.out.println(String.format("index:%s,num=%s", index,num));
    			Callable<Integer> callable = new Callable<Integer>() {
    
    
    				public Integer call() throws Exception {
    					int maxSleepNum = 10;
    					Integer sleepNum = new Random().nextInt(maxSleepNum);
    					System.out.println(String.format("SleepNum:%s", sleepNum));
    					Thread.sleep(sleepNum*1000);
    					return num;
    				}
    
    
    			};
    			//Future<Integer> task = new FutureTask<>(callable);
    			if(!executor.isShutdown()){
    				completionService.submit(callable);
    			}
    		}
    		Integer sum = 0;
    		for (int index = 1; index <= maxIndex; index++) {
    			try {
    				//查询最新1个完成的任务,然后删除
    				//Retrieves and removes the Future representing the next completed task, waiting if none are yet present.
    				Future<Integer> future = completionService.take();
    				Integer num = future.get();
    				System.out.println(String.format("num=%s",num));
    				sum += num;
    			} catch (InterruptedException | ExecutionException e) {
    				e.printStackTrace();
    			}
    
    
    		}
    		executor.shutdownNow();
    		System.out.println(sum);
    	}
    
    
    }







    在例子2的基础上,改了点,就是题目所要的效果。
    例子3:

     

    package cn.fansunion.executorservice; 

     

    import java.util.Arrays; 

    import java.util.Collections; 

    import java.util.Random; 

    import java.util.concurrent.Callable; 

    import java.util.concurrent.CompletionService; 

    import java.util.concurrent.ExecutionException; 

    import java.util.concurrent.ExecutorCompletionService; 

    import java.util.concurrent.Future; 

    import java.util.concurrent.LinkedBlockingQueue; 

    import java.util.concurrent.ThreadPoolExecutor; 

    import java.util.concurrent.TimeUnit; 

    /**

    * CompletionService,先获得,最快得到结果的那个线程的值

    * pool方法,可以设置超时时间

    *

    */ 

    public class FutureTaskTest3 { 

     

        public static void main(String[] args) { 

            // 【强制】线程池不允许使用 Executors ExecutorsExecutors 

            // 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor 

            // ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。 

            int nThreads = 5

            ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, 

                    new LinkedBlockingQueue<Runnable>(1000)); 

            CompletionService<Integer> completionService= new ExecutorCompletionService<Integer>(executor); 

            int maxIndex = 100

            //1到100求和 

           for (int index = 1; index <= maxIndex; index++) { 

                Integer num = index; 

                System.out.println(String.format("index:%s,num=%s", index,num)); 

                Callable<Integer> callable = new Callable<Integer>() { 

     

                    public Integer call() throws Exception { 

                        //让一部分超时 

                     int maxSleepNum = 350

                      Integer sleepNum = new Random().nextInt(maxSleepNum); 

                        System.out.println(String.format("SleepNum:%s", sleepNum)); 

                        //模拟计算时间,比如从远程查询数据 

                        Thread.sleep(sleepNum); 

                        return num; 

                    } 

     

                }; 

               //Future<Integer> task = new FutureTask<>(callable); 

                if(!executor.isShutdown()){ 

                    completionService.submit(callable); 

                } 

            } 

            //所有成功返回的num 

            Integer[] taskNumArray = new Integer[maxIndex]; 

            for (int index = 1; index <= maxIndex; index++) { 

                try

                    //等待下1个完成的任务,然后删除,但是最多等待一定的时间 

                    Future<Integer> future = completionService.poll(100, TimeUnit.MILLISECONDS); 

                    //模拟100毫秒,方便模拟超时,程序快点执行 

                    if(future==null){ 

                        break

                   } 

                  Integer num = future.get(); 

                   taskNumArray[index-1]=num; 

                    System.out.println(String.format("num=%s,成功返回1个数据",num)); 

                } catch (InterruptedException | ExecutionException e) { 

                    e.printStackTrace(); 

               } 

     

           }    

            executor.shutdownNow(); 

            Integer sum = 0

            //Collections.sort(Arrays.asList(taskNumArray)); 

            //System.out.println(taskNumArray); 

            for(Integer num:taskNumArray){ 

                //超时的那几个,么有值,位置是空的 

               if(num != null){ 

                    System.out.print(num+","); 

                    sum+= num; 

                } 

            } 

            System.out.println(); 

            System.out.println(String.format("sum=%s", sum)); 

        } 

     

    package cn.fansunion.executorservice;
    
    
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.Future;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    /**
     * CompletionService,先获得,最快得到结果的那个线程的值
     * pool方法,可以设置超时时间
     *
     */
    public class FutureTaskTest3 {
    
    
    	public static void main(String[] args) {
    		// 【强制】线程池不允许使用 Executors ExecutorsExecutors
    		// 去创建,而是通过 去创建,而是通过 去创建,而是通过 ThreadPoolExecutor
    		// ThreadPoolExecutor的方式,这样 的方式,这样 的处理方式让写同学更加明确线程池运行规则,避资源耗尽风险。
    		int nThreads = 5;
    		ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
    				new LinkedBlockingQueue<Runnable>(1000));
    		CompletionService<Integer> completionService= new ExecutorCompletionService<Integer>(executor);
    		int maxIndex = 100;
    		//1到100求和
    		for (int index = 1; index <= maxIndex; index++) {
    			Integer num = index;
    			System.out.println(String.format("index:%s,num=%s", index,num));
    			Callable<Integer> callable = new Callable<Integer>() {
    
    
    				public Integer call() throws Exception {
    					//让一部分超时
    					int maxSleepNum = 350;
    					Integer sleepNum = new Random().nextInt(maxSleepNum);
    					System.out.println(String.format("SleepNum:%s", sleepNum));
    					//模拟计算时间,比如从远程查询数据
    					Thread.sleep(sleepNum);
    					return num;
    				}
    
    
    			};
    			//Future<Integer> task = new FutureTask<>(callable);
    			if(!executor.isShutdown()){
    				completionService.submit(callable);
    			}
    		}
    		//所有成功返回的num
    		Integer[] taskNumArray = new Integer[maxIndex];
    		for (int index = 1; index <= maxIndex; index++) {
    			try {
    				//等待下1个完成的任务,然后删除,但是最多等待一定的时间
    				Future<Integer> future = completionService.poll(100, TimeUnit.MILLISECONDS);
    				//模拟100毫秒,方便模拟超时,程序快点执行
    				if(future==null){
    					break;
    				}
    				Integer num = future.get();
    				taskNumArray[index-1]=num;
    				System.out.println(String.format("num=%s,成功返回1个数据",num));
    			} catch (InterruptedException | ExecutionException e) {
    				e.printStackTrace();
    			}
    
    
    		}	
    		executor.shutdownNow();
    		Integer sum = 0;
    		//Collections.sort(Arrays.asList(taskNumArray));
    		//System.out.println(taskNumArray);
    		for(Integer num:taskNumArray){
    			//超时的那几个,么有值,位置是空的
    			if(num != null){
    				System.out.print(num+",");
    				sum+= num;
    			}
    		}
    		System.out.println();
    		System.out.println(String.format("sum=%s", sum));
    	}
    
    
    }





    输出结果(每次都是随机的):
    num=53,成功返回1个数据
    SleepNum:1
    num=56,成功返回1个数据
    SleepNum:296
    num=61,成功返回1个数据
    1,5,3,6,2,4,8,11,7,14,10,13,17,15,9,19,16,22,12,20,23,24,25,18,21,26,30,27,29,28,33,35,31,37,34,38,40,32,42,39,36,45,46,48,41,43,50,49,47,52,44,55,51,54,53,56,61,
    sum=1657

    }

                    } 

     

     

                }); 

                if(!executor.isShutdown()){ 

                    executor.submit(task); 

                } 

                taskList.add(task); 

            } 

            Integer sum = 0

            for (FutureTask<Integer> task : taskList) { 

                try

                    //阻塞,Waits if necessary for the computation to complete, and then retrieves its result. 

                    Integer num = task.get(); 

                    System.out.println(String.format("num=%s",num)); 

                    sum += num; 

                } catch (InterruptedException | ExecutionException e) { 

                    e.printStackTrace(); 

                } 

     

     

            } 

            executor.shutdownNow(); 

            System.out.println(sum); 

        } 

     

     

    展开全文
  • 试过在子线程中直接输出list,输出的list值,因为arrylist线程不安全,所以会报错。 但是我以上面代码运行时,代码不报错,但是list没有值。 想问一下为什么list没有值。  ...
  • https://www.cnblogs.com/transmuse/archive/2011/05/16/2048073.html 转载于:https://www.cnblogs.com/genggeng/p/9806415.html
  • 主线程等待多个子线程执行完才继续执行,以下是我能想到的几种方法,欢迎讨论、指正。1.闭锁CountDownLatch闭锁是典型的等待事件发生的同步工具类,将闭锁的初始值设置为与子线程数目相同,每个子线程执行完成都调用...
  • 主线程有多个handler的情况  工作中遇到了这么一种情况,有两个视图,都需要开启异步任务从服务器获取数据,每个view中创建一个Handler,注册到异步任务中去,当异步任务从服务器获取数据出错,或者出现io异常...
  • 主线程

    2020-05-03 19:54:05
    终于找到一主线程的了,居然在书里面没有找到详细讲的,在B站的视频里找到了讲这的,看来时候光看书还不够,虽然我买了很Linux编程的书了。 ...
  • 今天看到的有意思的问题(如题) ...上代码( 测试代码,错请一定告知….) public class MainActivity extends AppCompatActivity { private Handler mHandler = new Handler(){ @Override public void handleMes
  • 想一想, 一天你想测试某个方法的性能,你可能会这么去做,你先开启多个线程,然后记录下多个线程的执行总时间,当多个线程全部执行完毕时,回到主线程将时间打印出来...问题在于,你怎么来控制主线程要在全部子线...
  • 主线程和子线程区别: 主线程一般是,当一个程序启动时伴随着一个线程立即运行...每个进程至少都个主线程 主线程的重要性体现在两方面:1.是产生其他子线程的线程;2.通常它必须最后完成执行比如执行各种关闭动作。
  • 主线程和子线程通信

    2019-11-18 22:22:06
    默认情况下新增的线程是没有开启消息循环的(主线程除外,会默认创建Looper对象,开启消息循环) 一般情况下都是子线程向主线程发送消息,主线程...一个消息队列只有一个管家,但是Handler(工人)可以有多个。Loo...
  • 自己学着编写的一JAVA线程程序,该程序实现的功能是:在主线程main中创建两子线程,A和B,线程A先运行,再运行B线程,当两子线程都运行完毕后,才运行主线程,并最终结束整个程序的运行。 希望该程序对初学...
  • 方法,该子线程执行完后便减一,主线程中子线程的start后调用cDownLatch.await();方法,实现主线程等待并发子线程。 以下代码是实现线程进行一文件的读写,相当于复制了。目的是为实现线程并发,虽然速度上还...
  • Python 多个线程按先后顺序执行,并保持各子线程和主线程的通信 摘要 最近个项目使用pyqt5写的界面,界面展示部分作为项目的主线程,另外通过调用Thread,传入不同的参数又设置了五个子线程,因为第一个子线程的...
  • Java中的主线程

    2020-06-24 23:15:25
    当时感觉这个描述很奇怪,所以就来研究下这个主线程的确切语义。 Java提供了内置的多线程编程支持,多线程包括两个或多个可并发执行的部分,每一部分叫做线程,每个线程定义了单独的执行部分。 主线程 当一个Java...
  • 我们经常会需要创建线程,并且时候也需要等待线程执行完毕才能继续执行 下面这篇文章挺经典的,值得一看 http://www.iteye.com/topic/581476?page=2
  • Win32线程之主线程

    2013-11-18 21:58:57
    主线程有特点:  第一,它不许负责GUI(Graphic User Interface)程序中的主消息循环;  第二,这一线程结束(不论是因为返回或因为调用了ExitThread())会使得程序中的所有线程都被迫结束。程序也因此而...
  • 委托可以包含多个方法体,利用this.Invoke去执行。 也可以定义多种方法体,放在Thread里面去执行。则此方法体均为子线程。注意如果要修改UI界面的显示。则需要使用this.Invoke,否则会报异常。 Main函数为主线程...
  • 最近项目有个新的需求,大致意思是,前端发给我一系列ip(上千),需要我远程调用其他微服务,通过ip得到我所需要的返回结果。由于数量过大,不能一次性将1000ip都去调用其他微服务接口,可能会出现问题,并且...
  • 话说实现线程两种方式,这大家想必都知道吧,一是实现Runnable接口,实现run方法,一是继承Thread类,重写run方法,实现Runnable接口,还是需要包装到new Thread(runnable).start()来调用这线程。...
  •  工作中遇到了这么一种情况,视图,都需要开启异步任务从服务器获取数据,每view中创建一Handler,注册到异步任务中去,当异步任务从服务器获取数据出错,或者出现io异常或者http协议异常的时候,使用这...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,953
精华内容 2,781
关键字:

有多个主线程