java编程的总结与思考

可以用BlockingQueue来实现生产者-消费者并发模型(下一节中有介绍),当然在Java 5以前也可以通过wait和notify来实现线程调度,比较一下两种代码就知道基于已有的并发工具类来重构并发代码到底好在哪里了。 基于wait和notify的实现 使用BlockingQueue后代码优雅了很多。 并发模型 在继续下面的探讨之前,我们还是重温一下几个概念: 概念 解释临界资源 并发环境中有着固定数量的资源互斥 对资源的访问是排他式的饥饿 一个或一组线程长时间或永远无法取得进展死锁 两个或多个线程相互等待对方结束活锁 想要执行的线程总是发现其他的线程正在执行以至于长时间或永远无法执行重温了这几个概念后,我们可以探讨一下下面的几种并发模型。 生产者-消费者 一个或多个生产者创建某些工作并将其置于缓冲区或队列中,一个或多个消费者会从队列中获得这些工作并完成之。这里的缓冲区或队列是临界资源。当缓冲区或队列放满的时候,生产这会被阻塞;而缓冲区或队列为空的时候,消费者会被阻塞。生产者和消费者的调度是通过二者相互交换信号完成的。 读者-写者 当存在一个主要为读者提供信息的共享资源,它偶尔会被写者更新,但是需要考虑系统的吞吐量,又要防止饥饿和陈旧资源得不到更新的问题。

在这种并发模型中,如何平衡读者和写者是最困难的,当然这个问题至今还是一个被热议的问题,恐怕必须根据具体的场景来提供合适的解决方案而没有那种放之四海而皆准的方法(不像我在国内的科研文献中看到的那样)。 哲学家进餐 1965年,荷兰计算机科学家图灵奖得主Edsger Wybe Dijkstra提出并解决了一个他称之为哲学家进餐的同步问题。这个问题可以简单地描述如下:五个哲学家围坐在一张圆桌周围,每个哲学家面前都有一盘通心粉。由于通心粉很滑,所以需要两把叉子才能夹住。相邻两个盘子之间放有一把叉子如下图所示。哲学家的生活中有两种交替活动时段:即吃饭和思考。当一个哲学家觉得饿了时,他就试图分两次去取其左边和右边的叉子,每次拿一把,但不分次序。如果成功地得到了两把叉子,就开始吃饭,吃完后放下叉子继续思考。 把上面问题中的哲学家换成线程,把叉子换成竞争的临界资源,上面的问题就是线程竞争资源的问题。如果没有经过精心的设计,系统就会出现死锁、活锁、吞吐量下降等问题。 下面是用信号量原语来解决哲学家进餐问题的代码,使用了Java 5并发工具包中的Semaphore类(代码不够漂亮但是已经足以说明问题了)。 //import java.util.concurrent.ExecutorService; //import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; 现实中的并发问题基本上都是这三种模型或者是这三种模型的变体。 测试并发代码 对并发代码的测试也是非常棘手的事情,棘手到无需说明大家也很清楚的程度,所以这里我们只是探讨一下如何解决这个棘手的问题。

我们建议大家编写一些能够发现问题的测试并经常性的在不同的配置和不同的负载下运行这些测试。不要忽略掉任何一次失败的测试,线程代码中的缺陷可能在上万次测试中仅仅出现一次。具体来说有这么几个注意事项: 不要将系统的失效归结于偶发事件,就像拉不出屎的时候不能怪地球没有引力。先让非并发代码工作起来,不要试图同时找到并发和非并发代码中的缺陷。编写可以在不同配置环境下运行的线程代码。编写容易调整的线程代码,这样可以调整线程使性能达到最优。让线程的数量多于CPU或CPU核心的数量,这样CPU调度切换过程中潜在的问题才会暴露出来。

让并发代码在不同的平台上运行。通过自动化或者硬编码的方式向并发代码中加入一些辅助测试的代码。 Java 7的并发编程 Java 7中引入了TransferQueue,它比BlockingQueue多了一个叫transfer的方法,如果接收线程处于等待状态,该操作可以马上将任务交给它,否则就会阻塞直至取走该任务的线程出现。可以用TransferQueue代替BlockingQueue,因为它可以获得更好的性能。 刚才忘记了一件事情,Java 5中还引入了Callable接口、Future接口和FutureTask接口,通过他们也可以构建并发应用程序,代码如下所示。 Callable接口也是一个单方法接口,显然这是一个回调方法,类似于函数式编程中的回调函数,在Java 8 以前,Java中还不能使用Lambda表达式来简化这种函数式编程。和Runnable接口不同的是Callable接口的回调方法call方法会返回一个对象,这个对象可以用将来时的方式在线程执行结束的时候获得信息。上面代码中的call方法就是将计算出的10000个0到1之间的随机小数的平均值返回,我们通过一个Future接口的对象得到了这个返回值。目前最新的Java版本中,Callable接口和Runnable接口都被打上了@FunctionalInterface的注解,也就是说它可以用函数式编程的方式(Lambda表达式)创建接口对象。 下面是Future接口的主要方法: get():获取结果。如果结果还没有准备好,get方法会阻塞直到取得结果;当然也可以通过参数设置阻塞超时时间。 cancel():在运算结束前取消。 isDone():可以用来判断运算是否结束。 Java 7中还提供了分支/合并(fork/join)框架,它可以实现线程池中任务的自动调度,并且这种调度对用户来说是透明的。

为了达到这种效果,必须按照用户指定的方式对任务进行分解,然后再将分解出的小型任务的执行结果合并成原来任务的执行结果。这显然是运用了分治法(divide-and-conquer)的思想。下面的代码使用了分支/合并框架来计算1到10000的和,当然对于如此简单的任务根本不需要分支/合并框架,因为分支和合并本身也会带来一定的开销,但是这里我们只是探索一下在代码中如何使用分支/合并框架,让我们的代码能够充分利用现代多核CPU的强大运算能力。 伴随着Java 7的到来,Java中默认的数组排序算法已经不再是经典的快速排序(双枢轴快速排序)了,新的排序算法叫TimSort,它是归并排序和插入排序的混合体,TimSort可以通过分支合并框架充分利用现代处理器的多核特性,从而获得更好的性能(更短的排序时间)。

Java编程思考_java编程的总结与思考相关推荐

  1. java没思路_Java编程没思路写不出代码怎么办

    成功不是你想要就能得到的,而是需要你不断努力争取的.时间飞逝转眼间已经学习java编程近一个月了.从零基础到现在能够自己独立完成一段完整的代码,成就感驱使着我学习更多的知识,做出更加优秀的作品. 1. ...

  2. java软件自学_Java编程自学软件下载

    有一些用户在下载软件时没有仔细查看软件的下载量及软件评论什么的,导致下载的软件总是出现各种问题,其实,你只要看看这款软件的评论及下载量,你就可以知道这款软件是不是好软件,也确实是太多的软件不值得去下载 ...

  3. java 异步事件_Java编程入门——异步事件:轮询与中断

    CPU几乎把所有的时间都花费在从内存获取指令并运行它们的过程中.然而,CPU和主存仅仅只是计算机硬件系统中众多组件的其中两个.一个完整的系统还包含其他的设备,比如: 硬盘或者固态硬盘,用来存储程序和数 ...

  4. java 字符串编程题_Java编程题——在一个字符串中查找第一个非重复的字符

    编写一个Java程序来查找一个字符串中第一个非重复的字符,这是在编程测试中很常见的一个问题,因为字符串处理在程序员面试中是一个普遍的话题.面试前最好是准备好一些熟知的编程问题,例如使用递归反转字符串, ...

  5. java里冒泡排序编程案例_java编程题:用Java实现一个冒泡排序算法

    /** * java编程题:用Java实现一个冒泡排序算法 */ public class Test12 { public static void main(String[] args) { int[ ...

  6. java培训机构_java编程软件培训机构

    java编程软件培训机构,南京小码王科技培训有限公司,欢迎来电预约试听课:13851536647(郑老师)小码王实施以成就感驱动发自内在的建构主义教育,以面向未来高层次人才素质模型为导向,锻炼学生抽象 ...

  7. java 令牌解析_Java编程guava RateLimiter实例解析

    本文主要研究的是Java编程guava RateLimiter的相关内容,具体如下. 场景1 在流量监管中的应用 约定访问速率(CAR)是流量监管常用技术之一,可以应用在端口进和出方向,一般应用在入方 ...

  8. java 正方形字符串_java编程:怎么画一个正方形?

    问题描述: java编程:怎么画一个正方形? 不用applet,只是application编程,用java怎么画一个蓝色的正方形(最好实心和空心的各画一个). -------------------- ...

  9. java的成员方法_java编程中的成员方法是什么?

    DIEA 成员方法描述对象所具有的功能或操作,反映对象的行为,是具有某种相对独立功能的程序模块.它与过去所说的子程序.函数等概念相当.一个类或对象可以有多个成员方法,对象通过执行它的成员方法对传来的消 ...

最新文章

  1. 媒体智能应用落地靠5G,视频社交需要想象力
  2. linux用户及权限
  3. Android中使用File文件进行数据存储
  4. ListView实现分页
  5. 提高SQL执行效率的16种方法
  6. 天猫双11菜鸟物流绿色减碳1.8万吨 120万人参与快递箱回收
  7. 服务器技术文件,服务端开发技术文档要包含什么?
  8. WINDOWS用VS2010开发NPAPI插件步骤
  9. mock.js那点事(上)
  10. 高效能人士的七个习惯_如何成为高效能人士?——《高效能人士的七个习惯》读后感...
  11. 格式转换器怎么修改视频文件?把kux格式转换成mp4的技巧
  12. 运营商 sni 服务器,加密或者丢失:加密SNI的工作机制
  13. PostgreSQL - 如何杀死被锁死的进程
  14. eNSP配置VLAN
  15. 【mysql】mysql 常用建表语句
  16. mysql时间分钟比较_MySql中时间比较方法 周 小时 分钟
  17. 武汉移动137和武汉电信189手机业务比较
  18. git pul 无法拉取代码问题
  19. 最新研究:朝九晚五可能会让你的身心受到巨大伤害!
  20. SCI:SCI论文写作技巧的详细攻略

热门文章

  1. MCN品牌贝壳视频完成数千万元Pre—B轮融资
  2. html css animate,animate.css
  3. 抠图用绿布还是蓝布_有翡:有翡投资七八亿,为啥播出就被骂烂片?你看槽点有多少...
  4. vue2中使用低版本swiper
  5. UVA 1631 Locker(HDU 4433)(DP)
  6. Java Spring Data Redis实战与配置参数详解 application.properties
  7. 使用FROM装数据而报错出现argument type mismatch的原因
  8. 微服务配合docker使用
  9. 虚拟机NAT连接断网解决办法
  10. CSS 滚动条样式【兼容chrome、Firefox、IE】