- 浏览: 379869 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
wangchong_kevin:
放在drawable-hdpi目录下的图片,如果在mdpi分辨 ...
BitmapFactory.Options 解决加载大图片OOM -
darren_nizna:
Netty 实战(精髓) http://gitlore. ...
Java NIO框架Netty教程(一) Hello Netty(转) -
大家来学习:
国内首部NIO+Netty5各种RPC架构实战演练课程观看地址 ...
Java NIO框架Netty教程(一) Hello Netty(转) -
lipeixiaoyu:
[color=red][/color]123
IOS UIView的clipsToBounds属性 -
ramon1989:
问一下,你的SimpleChannelHandler是哪个包下 ...
Java NIO框架Netty教程(一) Hello Netty(转)
并发编程意味着更智慧地工作,而不是更困难地工作
并发 Collections 提供了线程安全、经过良好调优的数据结构,简化了并发编程。然而,在一些情形下,开发人员需要更进一步,思考如何调节和/或限制线程执行。由于 java.util.concurrent
的总体目标是简化多线程编程,您可能希望该包包含同步实用程序,而它确实包含。
本文是 第 1 部分 的延续,将介绍几个比核心语言原语(监视器)更高级的同步结构,但它们还未包含在 Collection 类中。一旦您了解了这些锁和门的用途,使用它们将非常直观。
在一些企业系统中,开发人员经常需要限制未处理的特定资源请求(线程/操作)数量,事实上,限制有时候能够提高系统的吞吐量,因为它们减少了对特定资源的争用。尽管完全可以手动编写限制代码,但使用 Semaphore 类可以更轻松地完成此任务,它将帮您执行限制,如清单 1 所示:
import java.util.*;
import java.util.concurrent.*; public class SemApp { public static void main(String[] args) { Runnable limitedCall = new Runnable() { final Random rand = new Random(); final Semaphore available = new Semaphore(3); int count = 0; public void run() { int time = rand.nextInt(15); int num = count++; try { available.acquire(); System.out.println("Executing " + "long-running action for " + time + " seconds... #" + num); Thread.sleep(time * 1000); System.out.println("Done with #" + num + "!"); available.release(); } catch (InterruptedException intEx) { intEx.printStackTrace(); } } }; for (int i=0; i<10; i++) new Thread(limitedCall).start(); } }
|
即使本例中的 10 个线程都在运行(您可以对运行 SemApp
的 Java 进程执行 jstack
来验证),但只有 3 个线程是活跃的。在一个信号计数器释放之前,其他 7 个线程都处于空闲状态。(实际上,Semaphore
类支持一次获取和释放多个 permit,但这不适用于本场景。)
上例的运行结果如下所示:
如果 Semaphore
是允许一次进入一个(这可能会勾起一些流行夜总会的保安的记忆)线程的并发性类,那么 CountDownLatch
就像是赛马场的起跑门栅。此类持有所有空闲线程,直到满足特定条件,这时它将会一次释放所有这些线程。
import java.util.*; import java.util.concurrent.*; class Race { private Random rand = new Random(); private int distance = rand.nextInt(250); private CountDownLatch start; private CountDownLatch finish; private List<String> horses = new ArrayList<String>(); public Race(String... names) { this.horses.addAll(Arrays.asList(names)); } public void run() throws InterruptedException { System.out.println("And the horses are stepping up to the gate..."); final CountDownLatch start = new CountDownLatch(1); final CountDownLatch finish = new CountDownLatch(horses.size()); final List<String> places = Collections.synchronizedList(new ArrayList<String>()); for (final String h : horses) { new Thread(new Runnable() { public void run() { try { System.out.println(h + " stepping up to the gate..."); start.await(); int traveled = 0; while (traveled < distance) { // In a 0-2 second period of time.... Thread.sleep(rand.nextInt(3) * 1000); // ... a horse travels 0-14 lengths traveled += rand.nextInt(15); System.out.println(h + " advanced to " + traveled + "!"); } finish.countDown(); System.out.println(h + " crossed the finish!"); places.add(h); } catch (InterruptedException intEx) { System.out.println("ABORTING RACE!!!"); intEx.printStackTrace(); } } }).start(); } System.out.println("And... they're off!"); start.countDown(); finish.await(); System.out.println("And we have our winners!"); System.out.println(places.get(0) + " took the gold..."); System.out.println(places.get(1) + " got the silver..."); System.out.println("and " + places.get(2) + " took home the bronze."); } } public class CDLApp { public static void main(String[] args) throws InterruptedException, java.io.IOException { System.out.println("Prepping..."); Race r = new Race( "Beverly Takes a Bath", "RockerHorse", "Phineas", "Ferb", "Tin Cup", "I'm Faster Than a Monkey", "Glue Factory Reject" ); System.out.println("It's a race of " + r.getDistance() + " lengths"); System.out.println("Press Enter to run the race...."); System.in.read(); r.run(); } }
|
注意,在 清单 2 中,CountDownLatch
有两个用途:首先,它同时释放所有线程,模拟马赛的起点,但随后会设置一个门闩模拟马赛的终点。这样,“主” 线程就可以输出结果。 为了让马赛有更多的输出注释,可以在赛场的 “转弯处” 和 “半程” 点,比如赛马跨过跑道的四分之一、二分之一和四分之三线时,添加 CountDownLatch
。
上例的运行结果如下所示:
清单 1 和 清单 2 中的示例都存在一个重要的缺陷,它们要求您直接创建 Thread
对象。这可以解决一些问题,因为在一些 JVM 中,创建 Thread
是一项重量型的操作,重用现有 Thread
比创建新线程要容易得多。而在另一些 JVM 中,情况正好相反:Thread
是轻量型的,可以在需要时很容易地新建一个线程。当然,如果 Murphy 拥有自己的解决办法(他通常都会拥有),那么您无论使用哪种方法对于您最终将部署的平台都是不对的。
JSR-166 专家组(参见 参考资料)在一定程度上预测到了这一情形。Java 开发人员无需直接创建 Thread
,他们引入了 Executor
接口,这是对创建新线程的一种抽象。如清单 3 所示,Executor
使您不必亲自对 Thread
对象执行 new
就能够创建新线程:
Executor exec = getAnExecutorFromSomeplace(); exec.execute(new Runnable() { ... });
|
使用 Executor
的主要缺陷与我们在所有工厂中遇到的一样:工厂必须来自某个位置。不幸的是,与 CLR 不同,JVM 没有附带一个标准的 VM 级线程池。
Executor
类实际上 充当着一个提供 Executor
实现实例的共同位置,但它只有 new
方法(例如用于创建新线程池);它没有预先创建实例。所以您可以自行决定是否希望在代码中创建和使用 Executor
实例。(或者在某些情况下,您将能够使用所选的容器/平台提供的实例。)
尽管不必担心 Thread
来自何处,但 Executor
接口缺乏 Java 开发人员可能期望的某种功能,比如结束一个用于生成结果的线程并以非阻塞方式等待结果可用。(这是桌面应用程序的一个常见需求,用户将执行需要访问数据库的 UI 操作,然后如果该操作花费了很长时间,可能希望在它完成之前取消它。)
对于此问题,JSR-166 专家创建了一个更加有用的抽象(ExecutorService
接口),它将线程启动工厂建模为一个可集中控制的服务。例如,无需每执行一项任务就调用一次 execute()
,ExecutorService
可以接受一组任务并返回一个表示每项任务的未来结果的未来列表。
尽管 ExecutorService
接口非常有用,但某些任务仍需要以计划方式执行,比如以确定的时间间隔或在特定时间执行给定的任务。这就是 ScheduledExecutorService
的应用范围,它扩展了 ExecutorService
。
如果您的目标是创建一个每隔 5 秒跳一次的 “心跳” 命令,使用 ScheduledExecutorService
可以轻松实现,如清单 4 所示:
清单 4. ScheduledExecutorService 模拟心跳
import java.util.concurrent.*; public class Ping { public static void main(String[] args) { ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); Runnable pinger = new Runnable() { public void run() { System.out.println("PING!"); } }; ses.scheduleAtFixedRate(pinger, 5, 5, TimeUnit.SECONDS); } }
|
这项功能怎么样?不用过于担心线程,不用过于担心用户希望取消心跳时会发生什么,也不用明确地将线程标记为前台或后台;只需将所有的计划细节留给 ScheduledExecutorService
。
顺便说一下,如果用户希望取消心跳,scheduleAtFixedRate
调用将返回一个 ScheduledFuture
实例,它不仅封装了结果(如果有),还拥有一个 cancel
方法来关闭计划的操作。
为阻塞操作设置一个具体的超时值(以避免死锁)的能力是 java.util.concurrent
库相比起早期并发特性的一大进步,比如监控锁定。
这些方法几乎总是包含一个 int
/TimeUnit
对,指示这些方法应该等待多长时间才释放控制权并将其返回给程序。它需要开发人员执行更多工作 — 如果没有获取锁,您将如何重新获取? — 但结果几乎总是正确的:更少的死锁和更加适合生产的代码。(关于编写生产就绪代码的更多信息,请参见 参考资料 中 Michael Nygard 编写的 Release It!。)
java.util.concurrent
包还包含了其他许多好用的实用程序,它们很好地扩展到了 Collections 之外,尤其是在 .locks
和 .atomic
包中。深入研究,您还将发现一些有用的控制结构,比如 CyclicBarrier
等。
发表评论
-
tomcat下jsp乱码原因(下)
2015-09-16 14:13 717转自:http://blog.csdn.net/jgwei/ ... -
tomcat 下jsp乱码的原因分析(上)
2015-09-16 14:10 703转自 http://blog.csdn.net/jgwei/ ... -
JAVA数据源连接方式汇总
2015-07-23 10:28 869一、问题引入 在java程序中,需要访问数据库,做增删改查 ... -
java初始化块和构造方法的执行顺序
2015-06-09 11:18 661初始化块是ja ... -
Java 内存分配全面浅析
2014-02-20 10:56 778本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更 ... -
java 24小时和12小时制
2013-04-12 11:39 1219Date类,已经很少用了。用Calendar吧。 Calen ... -
BlockingQueue
2013-04-08 12:07 1023前言: 在新增的Concu ... -
Java NIO框架Netty教程(四) ChannelBuffer(转)
2013-03-01 10:34 8097在学字符串消息收发(ht ... -
Java NIO框架Netty教程(三) 字符串消息收发(转)
2013-03-01 10:31 6422了解了Netty的基本概念( ... -
Java NIO框架Netty教程(二) 白话概念(转)
2013-03-01 10:20 7847"Hello World"的代 ... -
Java NIO框架Netty教程(一) Hello Netty(转)
2013-03-01 10:16 48839先啰嗦两句,如果你还不知道Netty是做什么的能做什么。那 ... -
Netty Channel 接口名词理解
2013-02-28 18:56 29651.Channel channel 是负责数据读,写的对象 ... -
Java中使用默认的密钥库和算法创建数字证书
2012-11-15 09:42 1208★ 实例说明 本实例使 ... -
keystore提取私钥和证书
2012-11-15 09:41 2022keytool -genkey -alias test -ke ... -
详细讲KeyTool
2012-11-15 09:39 1★ 实例说明 本实例使用J2SDK提供的keytool工具 ... -
http获取文件大小
2012-09-21 10:03 2102URL url = new URL(downloadUrl); ... -
android内存管理
2012-03-16 10:56 1很多开发者都是从j2me或j2ee上过来的,对于内存的使用和理 ... -
Playing Flash FLV Videos in Android applications
2012-03-14 14:37 1671Often when you create an app di ... -
调用Android系统“应用程序信息(Application Info)”界面
2012-02-21 18:45 0“Android系统设置->应 ... -
AsyncTask解决Android UI堵塞问题
2012-02-17 14:54 0AsyncTask解决Android UI堵 ...
相关推荐
CAS就这?一. CAS是什么?二....import java.util.concurrent.atomic.AtomicInteger; /** * 1. CAS是什么? => compareAndSet 比较并交换 */ public class CASTest { public static void main(Strin
内容概要:本文介绍了如何利用CST软件进行三维超材料的能带计算。首先概述了三维超材料的独特性质及其广泛应用前景,接着简要介绍了CST软件的功能特点。随后详细阐述了能带计算的具体步骤,包括模型建立、材料参数设置、网格划分与求解设置以及最终的计算与结果分析。最后给出了一段Python代码示例,展示了如何处理CST输出的数据并绘制能带图。文章强调了计算机模拟技术对于深入了解超材料电子结构和物理性质的重要性。 适合人群:从事材料科学研究的专业人士,尤其是对三维超材料和电磁场模拟感兴趣的科研工作者和技术人员。 使用场景及目标:适用于希望借助CST软件开展三维超材料能带计算的研究项目,旨在提高对超材料的理解,推动相关领域的技术创新和发展。 其他说明:文中提供的Python代码仅为示例,在实际操作时可根据具体情况进行调整优化。同时,掌握CST软件的基本操作和电磁理论基础知识有助于更好地理解和应用本文内容。
内容概要:本文详细介绍了基于FPGA的永磁同步伺服系统的矢量控制设计,涵盖了从电流环到速度环的关键模块实现。具体包括Clarke和Park变换、PI调节器、AD7606采样、正交编码器反馈以及SVPWM生成等部分。文中提供了详细的Verilog代码片段,展示了各个模块的具体实现方法和技术细节。特别强调了定点数处理、时序设计和跨时钟域处理等方面的技术挑战及其解决方案。 适合人群:具备一定FPGA开发经验和电机控制基础知识的研发人员。 使用场景及目标:适用于希望深入了解FPGA在电机控制应用中的具体实现方式,特别是矢量控制和电流环设计的专业人士。目标是掌握FPGA平台下高效、低延迟的电机控制系统设计方法。 阅读建议:由于涉及大量具体的Verilog代码和硬件设计细节,建议读者在阅读过程中结合实际项目进行实验和调试,以便更好地理解和掌握相关技术。
经典飞机大战游戏是理解实时交互系统设计的绝佳载体。本文将深入剖析现代空战游戏的核心模块,涵盖刚体运动学、弹道轨迹优化、碰撞检测算法等关键技术,揭示二维游戏背后复杂的三维数学建模过程。
scratch少儿编程逻辑思维游戏源码-冰塔.zip
scratch少儿编程逻辑思维游戏源码-弹跳(4).zip
内容概要:本文详细介绍了COMSOL软件中三种常见的焊接热源模型——双椭球热源、高斯旋转体热源和柱状体热源。双椭球热源适用于模拟移动热源(如激光焊、电弧焊),通过调整轴向系数a1和a2来控制热流分布;高斯旋转体热源适合小范围焊接,采用三维高斯函数描述热流密度;柱状体热源则用于深熔焊场景,特点是计算速度快。文中还提供了每种模型的具体代码实现,并强调了调试时需要注意的关键点,如时间步长、网格加密等。此外,作者分享了一些实用技巧,如将热源参数设置为全局变量并利用参数扫描功能提高调试效率。 适合人群:从事焊接工艺仿真、材料加工领域的研究人员和技术人员,以及对COMSOL建模感兴趣的工程技术人员。 使用场景及目标:帮助用户选择合适的热源模型进行焊接模拟,确保模拟结果的准确性;提供具体的代码实现和调试方法,使用户能够快速掌握并应用于实际项目中。 其他说明:文中提到的热源模型不仅限于理论介绍,还包括实际操作中的注意事项和优化建议,有助于提升模拟效果和工作效率。
内容概要:本文介绍了将基于RBF神经网络的PID控制器应用于永磁同步电机(PMSM)转速环控制的方法及其性能优势。传统的PID控制器在面对非线性和时变系统时存在参数整定困难的问题,而引入RBF神经网络可以实现实时在线调参,提高系统的灵活性和鲁棒性。文中详细描述了Simulink模型的设计,特别是Matlab s-function模块中RBF神经网络的具体实现,包括高斯函数激活和带惯性的权值更新机制。实验结果显示,在转速突变情况下,改进后的控制器能够迅速稳定系统,超调量控制在2%以内,调节时间较传统方法缩短约40%,并且在负载变化时表现出色,无需重新整定参数。 适合人群:从事电机控制系统研究和开发的技术人员,尤其是对PID控制器优化感兴趣的工程师。 使用场景及目标:适用于需要提升PMSM转速环控制精度和响应速度的应用场合,如工业自动化设备、机器人等领域。目标是通过引入智能算法解决传统PID控制器参数整定难题,提高系统性能。 阅读建议:关注RBF神经网络与PID控制器结合的具体实现细节,特别是在Matlab s-function模块中的编码技巧以及参数调整策略。同时,注意学习率的选择和动量项的作用,这对于实际应用至关重要。
scratch少儿编程逻辑思维游戏源码-GTA 6.zip
scratch少儿编程逻辑思维游戏源码-仓鼠跑酷.zip
scratch少儿编程逻辑思维游戏源码-超级麦克世界.zip
scratch少儿编程逻辑思维游戏源码-400年.zip
少儿编程scratch项目源代码文件案例素材-气球足球.zip
少儿编程scratch项目源代码文件案例素材-沙漠迷城.zip
scratch少儿编程逻辑思维游戏源码-比谁高.zip
少儿编程scratch项目源代码文件案例素材-乾坤大挪移.zip
scratch少儿编程逻辑思维游戏源码-菜鸟跳跃.zip
内容概要:本文档详细介绍了C++语言的基础知识、高级特性及其应用。首先,文档回顾了C++对C语言的扩展,包括面向对象编程的支持、增强的语法特性(如命名空间、引用、常量处理等)。接着,深入探讨了类和对象的使用,涵盖构造函数、析构函数、拷贝构造函数、深浅拷贝等重要概念。文档还讲解了单例模式的设计与实现、C++面向对象模型的核心要素(如this指针、静态成员、友元函数)、继承与派生的关系及其实现细节、多态性的原理与应用。此外,文档详细介绍了C++的模板机制、类型转换、异常处理机制、输入输出流操作、STL(标准模板库)的容器和算法等内容。每个部分都通过具体的代码示例和解释,帮助读者理解和掌握C++的关键特性和最佳实践。 适合人群:具备一定编程基础,尤其是熟悉C语言的开发者;希望深入了解C++语言特性和面向对象编程思想的程序员;从事C++开发工作的工程师和技术爱好者。 使用场景及目标:①掌握C++语言的核心概念和高级特性;②理解并能够应用面向对象编程的基本原则和模式;③学习如何使用STL容器和算法优化代码性能;④提升C++程序的健壮性和可维护性,特别是在处理复杂数据结构和算法时;⑤掌握异常处理和类型转换的最佳实践,确保程序的稳定性和安全性。 其他说明:本文档不仅提供了理论知识,还结合了大量实例代码,便于读者边学边练。对于每一个知识点,文档都力求做到详尽解释,确保读者能够透彻理解并灵活运用。文档内容全面覆盖了C++编程的各个方面,从基础语法到高级特性,适合不同层次的学习者逐步深入学习。
内容概要:本文详细探讨了电气铁路柔性过分相技术中的60°换相波形稳定问题。首先介绍了柔性过分相的基本概念及其重要性,接着重点讨论了60°换相波形稳定对系统运行效率和稳定性的影响。文中还阐述了实现换相波形稳定的多种方法,如先进控制算法、实时监测设备以及滤波器的应用。最后,通过引用相关文献和实例,进一步验证了换相波形稳定的重要性和可行性。 适合人群:从事电气铁路系统设计、维护的技术人员,以及对该领域感兴趣的科研人员。 使用场景及目标:适用于希望深入了解电气铁路柔性过分相技术的专业人士,旨在帮助他们掌握60°换相波形稳定的相关理论和技术手段,提升系统性能。 其他说明:文章结合了理论分析与实际案例,提供了丰富的参考资料,有助于读者全面理解并应用于实际工作中。
scratch少儿编程逻辑思维游戏源码-发动.zip