java 并发执行_Java并发执行器的懒惰开发人员简介

java 并发执行

如果我告诉您util.concurrent API自2004年起提供此类服务,我就会自欺欺人。但是,我想回顾一下一些很酷的功能。 并发专家,现在是时候关闭该窗口了。 所有其他人,请保持紧紧的乐趣。

你不会忘记你的根源

执行程序是具有单个执行方法的根接口。 任何实现Runnable接口的东西都可以作为参数传递。 但是,傻傻的执行器不支持Callable。

好消息: ExecutorService接口扩展了Executor,增加了对Callable的支持。 它的实现类是ThreadPoolExecutor。

我要假装ScheduledExecutorService接口及其实现类ScheduledThreadPoolExecutor不存在,因为它们只是在ExecutorService和ThreadPoolExecutor之上添加了调度功能。 但是,请记住此类,当功能强大但无聊的java.util.Timer不够用,而功能强大的外部调度程序实在太多了。

如果您不熟悉并发性,或者忘记了Callable和Runnable之间的区别,则可能需要先阅读一点,然后再继续阅读。 虚拟指南在这里

ExecutorService.submit事实:

这三个提交变量:

将来提交(可调用任务)
将来提交(可运行任务)
将来提交(可运行任务,T结果)

  1. 所述submit的的ExecutorService的方法过载并且可以接受一个CallableRunnable
  2. 由于Runnable的run方法返回void,因此在任务完成时Future.get总是返回null也就Future.get了。
    Future<?>   submit(Runnable task)
  3. 另一个接受Runnable和泛型的重载submit方法将返回您作为第二个参数传入的结果。
    <T> Future<T>   submit(Runnable task, T result)

事实上,开放代码( FutureTask ),你会发现, RunnableAdapter顶级嵌套类的Executors只需保存结果,并返回相同的结果run方法完成之后。

static final class RunnableAdapter<T> implements Callable<T> {final Runnable task;final T result;RunnableAdapter(Runnable task, T result) {this.task = task;this.result = result;}public T  [More ...] call() {task.run();return result;}
}

RunnableAdapter源

在这两种情况下,如果您想(应该!)终止程序,而不是执行程序线程阻止该程序并进入繁忙循环 ,则应按以下方式调用shutdown方法:

executorService.shutdown()

关闭事实

您可以想象shutdown是购物中心的半关门。 不会有新客户进入,但现有客户一旦完成就可以离开购物中心。

重申一下,

  1. shutdown是一种礼貌的方法。 它实际上并不会立即关闭池中的任务。 它只是说不会接受任何新任务。
  2. 除非您使用invokeAll执行任务,否则您将需要等待所有正在进行的任务完成。 这可以通过调用awaitTermination方法来实现。 (invokeAll并在帖子底部提交示例)
  3. 当前所有任务完成后,执行程序服务将关闭。

如果您需要一种不礼貌的入侵方法,而该方法不关心当前线程是否已完成其任务,那么shutdownNow是您的理想选择。 但是,不能保证该方法将关闭点上的服务,但是它是您必须立即关闭的最接近的方法。

在awaitTermination上,您可以指定超时时间,直到主线程等待池线程完成其任务为止。

ExecutorService executorService=Executors.newFixedThreadPool(10);…future = executorService.submit(getInstanceOfCallable(count,sum));…executorService.shutdown();if (executorService.awaitTermination(10, TimeUnit.SECONDS)){System.out.println('All threads done with their jobs');}

执行者–工厂的家伙

上面的课程都很棒。 但是,例如,您想创建一个单线程执行器,您将编写类似

new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());

比较一下

Executors.newSingleThreadExecutor()

所以,你去。 Executors是仅具有工厂方法的类,用于创建具有一些常用默认值的各种形式的executor服务。 请注意,除了很棒的工厂方法外,它没有为表带来任何新功能。

建议您快速查看工厂方法的实现,并检查它是否适合您的需求。

invokeAll和提交

ExecutorServiceinvokeAll方法的All部分毫不奇怪。 它只是说您需要传递Callable的Collection。 再次,正如预期的那样,该方法直到所有线程完成其任务后才返回。 因此,对于仅在所有工作完成后才对结果感兴趣的情况, invokeAll是您的最佳选择。

另一方面, submit方法将可调用对象提交给执行者服务后立即返回。 除非您在Callable call方法中什么都不做,否则理想情况下,当submit方法返回时,工作线程应该正在运行。

以下示例可能对您有用。 这些程序只是试图找到直到100的所有自然数的和(当然是蛮力)

package me.rerun.incubator;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;
import java.util.concurrent.atomic.AtomicInteger;public class ExecutorInvokeAll {public void runApp() throws InterruptedException, ExecutionException{//variable to store the sumAtomicInteger sum=new AtomicInteger();//Use our friendly neighbourhood factory method of the Executors.ExecutorService executorService=Executors.newFixedThreadPool(10);List<Callable<AtomicInteger>> callableList=new ArrayList<Callable<AtomicInteger>>();for (int count = 0; count <= 100;count++) {callableList.add(getInstanceOfCallable(count,sum));}//returns only after all tasks are completeList<Future<AtomicInteger>> resultFuture = executorService.invokeAll(callableList);//Prints 5050 all throughfor (Future<AtomicInteger> future : resultFuture) {//Didn't deliberately put a timeout here for the get method. Remember, the invoke All does not return until the task is done.System.out.println("Status of future : " + future.isDone() +". Result of future : "+future.get().get());}executorService.shutdown();// You might as well call a resultFuture.get(0).get().get() and that would give you the same //result since all your worker threads hold reference to the same atomicinteger sum.System.out.println("Final Sum : "+sum); }//Adds count to the sum and returns the reference of the sum as the resultprivate Callable<AtomicInteger> getInstanceOfCallable(final int count, final AtomicInteger sum) {Callable<AtomicInteger> clientPlanCall=new Callable<AtomicInteger>(){public AtomicInteger call() {sum.addAndGet(count);System.out.println("Intermediate sum :"+sum);return sum;}};return clientPlanCall;}public static void main(String[] args) throws ExecutionException {try {new ExecutorInvokeAll().runApp();} catch (InterruptedException e) {e.printStackTrace();}} }
package me.rerun.incubator;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;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;public class ExecutorSubmit {public void runApp() throws InterruptedException, ExecutionException{//holder for the total sumAtomicInteger sum=new AtomicInteger();//Use the factory method of ExecutorsExecutorService executorService=Executors.newFixedThreadPool(10);Future<AtomicInteger> future = null;for (int count = 0; count <= 100; count++) {future = executorService.submit(getInstanceOfCallable(count,sum));//prints intermediate sumtry {System.out.println("Status of future : " + future.isDone() +". Result of future : "+future.get(1000, TimeUnit.MILLISECONDS).get());} catch (TimeoutException e) {System.out.println("<IGNORE> Timeout exception for count : "+count);//e.printStackTrace();}//System.out.println("Result of future : "+future.get().get() +".Status of future : " + future.isDone());}executorService.shutdown();if (executorService.awaitTermination(10, TimeUnit.SECONDS)){System.out.println("All threads done with their jobs");}//execSystem.out.println("Final Sum : "+sum);}//Adds count to the sum and returns the reference of the sum as the resultprivate Callable<AtomicInteger> getInstanceOfCallable(final int count, final AtomicInteger sum) {Callable<AtomicInteger> clientPlanCall=new Callable<AtomicInteger>(){public AtomicInteger call() {sum.addAndGet(count);//System.out.println("Intermediate sum :"+sum);return sum;}};return clientPlanCall;}public static void main(String[] args) throws ExecutionException {try {new ExecutorSubmit().runApp();} catch (InterruptedException e) {e.printStackTrace();}} }

进一步阅读:

亚历克斯·米勒的惊人博客

亚历克斯·米勒的并发陷阱

Vogella关于与原始API进行比较的文章

总体上很好地介绍了并发

强烈推荐有关Java并发性的书

祝您编程愉快,别忘了分享!

参考: Rerun.me博客上的JCG合作伙伴 Arun Manivannan的Java并发执行器懒惰开发人员简介 。


翻译自: https://www.javacodegeeks.com/2012/10/a-lazy-developers-introduction-to-java.html

java 并发执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352800.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

球球大作战测试服android版,球球大作战10.0体验服

在球球大作战10.0体验服中&#xff0c;2019球球们将迎来全新的冒险&#xff0c;多重外观&#xff0c;更加的绚丽夺目&#xff0c;探索新的地图&#xff0c;与不同的对手较量一番&#xff0c;无限吞噬&#xff0c;热血竞技&#xff0c;灵活的走位&#xff0c;搭配强力道具&#…

单线程的并发,协程

IO多路复用 作用:检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据) setblocking(Flase) 让原本阻塞的变成非阻塞(不等待)状态 import socket import selectsk socket.socket() sk.setblocking(False) try:sk.connect(("www.baidu.com",80)) exce…

linux shell 字符串操作详解 (长度,读取,替换,截取,连接,对比,删除,位置 )

在做shell批处理程序时候&#xff0c;经常会涉及到字符串相关操作。有很多命令语句&#xff0c;如&#xff1a;awk,sed都可以做字符串各种操作。 其实shell内置一系列操作符号&#xff0c;可以达到类似效果&#xff0c;大家知道&#xff0c;使用内部操作符会省略启动外部程序等…

android.mk 模块编译,通过Android.mk添加一个编译模块到系统中的顺序如下

①LOCAL_PATH②CLEAR_VARS③LOCAL_SRC_FILES④LOCAL_CFLAGS(可选)⑤LOCAL_MODULE⑥LOCAL_STATIC_LIBRARIES(可选)⑦BUILD_XXX(12)Android.mk常用的变量变量名 说明LOCAL_PATH 用于确定源码所在的目录&#xff0c;最好把它放在CLEAR_VARS变量引用的前面&#xff0c;因为它不会被…

使用Spring Reactor Core进行分散收集

我在使用Netflix Rx-Java库方面有良好的工作经验&#xff0c;并且以前曾写过关于使用Rx-Java和Java 8 CompletableFuture解决分散式问题的博客。 在这里&#xff0c;我想探索使用Spring Reactor Core库应用相同的模式。 tldr –如果您熟悉Netflix Rx-Java&#xff0c;您已经很…

添加操作审计记录

1.所有操作审计记录 在环境变量/etc/profile中加入如下字段&#xff0c;可记录所有用户登录系统的操作 #history bash USERwhoami USER_IPwho -u am i 2>/dev/null| awk {print $NF}|sed -e s/[()]//g if [ "$USER_IP" "" ]; then USER_IPhostname fi …

android sharesdk分享功能,Android ShareSDK快速实现分享功能

第一步 &#xff1a;获取ShareSDK为了集成ShareSDK&#xff0c;您首先需要到ShareSDK官方网站注册并且创建应用&#xff0c;获得ShareSDK的Appkey&#xff0c;然后到SDK的下载页面下载SDK的压缩包&#xff0c;解压以后可以得到如下图的目录结构&#xff1a;ShareSDK在“ShareSD…

shell编程-分支语句

目标&#xff1a;完成这一章&#xff0c;你将能够作以下事情&#xff1a;描述条件分支语句中返回值的作用。 使用test命令来分析一个命令的返回值。 在shell程序中使用if和case结构。 1.返回值shell变量“&#xff1f;”中保存上一个被执行命令的返回值&#xff1a;0&#xff1…

android自定义表盘部件,Android自定义view仿支付宝芝麻信用表盘

演示效果实现步骤&#xff1a;1.画不同宽度和半径的内外圆弧2.通过循环旋转canvas&#xff0c;在固定位置绘制短线刻度&#xff0c;长线刻度&#xff0c;刻度文字3.绘制view中心几个文本&#xff0c;并调整位置4.实时更新当前旋转角度刷新小圆点位置&#xff1b;5.判断分数应该…

记录的详细操作

拷贝表拷贝结构 与数据create table copy_table select *from customer ;仅拷贝结构create table copy_table select *from customer where 0 > 1;共同点&#xff1a; 索引 描述&#xff08;自增&#xff09; 不能以下语法中记录的详细操作[] 表示可选的{}表示必选的增ins…

linux查看文件有多少行

使用wc命令 具体通过wc --help 可以查看。 如&#xff1a;wc -l filename 就是查看文件里有多少行 wc -w filename 看文件里有多少个word。 wc -L filename 文件里最长的那一行是多少个字。 wc命令 wc命令的功能为统计指定文件中的字节数、字数、行数, 并将统计结果显示输出。 …

java 消息通知_用Java弹出创建新的消息通知

java 消息通知首先创建JFrame作为弹出窗口。 在其中添加一些JLabel以包含信息&#xff0c;并在适当的位置分配它们&#xff0c;使其看起来像一条通知消息。 下面给出了示例代码&#xff1a; String message You got a new notification message. Isnt it awesome to have suc…

vs android 压缩,Android Studio是否压缩classes.dex文件?

看起来输出文件夹中apk文件的classes.dex与已安装的应用程序不同.我正在使用classes.dex文件来解决一些安全问题,所以通常我解压缩最终的apk文件并从classes.dex文件中获取信息.但是当我在运行时读取classes.dex文件时文件大小是如此不同. (8MB vs 46KB)应用程序本身工作得很好…

自己写的py文件中调用django models

import os os.environ[DJANGO_SETTINGS_MODULE] 项目名.settingsimport djangodjango.setup()from blog import modelsentry models.Entry.objects.get(pk1)tech_blog models.Blog.objects.get(name科技)print(entry, tech_blog) 转载于:https://www.cnblogs.com/dangrui072…

shell脚本 -d 是目录文件,那么-e,-f分别是什么?还有! -e这又是什么意思呢?

shell脚本 -d 是目录文件&#xff0c;那么-e&#xff0c;-f分别是什么?还有"&#xff01; -e"这又是什么意思呢&#xff1f; -e filename 如果 filename存在&#xff0c;则为真 -d filename 如果 filename为目录&#xff0c;则为真 -f filename 如果 filename为常规…

将Java应用程序作为Windows服务安装

这听起来像是您不需要的东西&#xff0c;但是有时候&#xff0c;当您分发最终用户软件时&#xff0c;可能需要将Java程序安装为Windows服务。 我之所以必须这样做&#xff0c;是因为我开发了一种用于公务员的工具 &#xff0c;可以自动将其Excel文件转换并将其推入我国的openda…

怎样实现banner自动播放html,纯CSS3实现banner图片自动轮播效果方式总结

自动轮播&#xff1a;实现切换图片&#xff0c;图片循环播放&#xff1b;鼠标悬停某张图片&#xff0c; 则暂停切换。css方法一、opacity控制透明度实现轮播效果依照需求咱们选择用CSS3的animation动画进行实现&#xff1b;transition动画须要触发才能启动&#xff0c;html因此…

你好a+b(非入门)

题目传送门&#xff1a;https://www.nowcoder.com/acm/contest/165/A来源&#xff1a;牛客网 牛牛刚学习了输入输出&#xff0c;他遇到了一道这样的题目。 输入2个整数a和b保证输入的a和b在long long范围之内&#xff0c;即满足-9223372036854775808 < a, b < 9223372036…

/etc/sysconfig/i18n文件详解

编辑/etc/sysconfig/i18n这个文件&#xff0c; 不管你装的是中文版,还是英文版.删掉原来的设置,把下面的拷贝过去 LANG"zh_CN.GB18030" SUPPORTED"zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en" SYSFONT"latarcyrheb-sun16" 保存,重起.OK了 这时…

201771010112罗松《面向对象程序设计(java)》第三周学习总结

实验三 Java基本程序设计 201771010112 罗松 1、实验目的与要求 &#xff08;1&#xff09;进一步掌握Eclipse集成开发环境下java程序开发基本步骤&#xff1b; &#xff08;2&#xff09;熟悉PTA平台线上测试环境&#xff1b; &#xff08;3&#xff09;掌握Java语言构造基本…