??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品97,91社区在线,国产欧美日韩精品高清二区综合区 http://www.aygfsteel.com/java-blog/category/26886.htmlzh-cnSat, 27 Oct 2007 08:31:42 GMTSat, 27 Oct 2007 08:31:42 GMT60生?消费者模?/title><link>http://www.aygfsteel.com/java-blog/articles/156355.html</link><dc:creator>一步一步努力向上爬</dc:creator><author>一步一步努力向上爬</author><pubDate>Sat, 27 Oct 2007 08:23:00 GMT</pubDate><guid>http://www.aygfsteel.com/java-blog/articles/156355.html</guid><wfw:comment>http://www.aygfsteel.com/java-blog/comments/156355.html</wfw:comment><comments>http://www.aygfsteel.com/java-blog/articles/156355.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/java-blog/comments/commentRss/156355.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/java-blog/services/trackbacks/156355.html</trackback:ping><description><![CDATA[<span><span> 生?消费者模型是最基本的ƈ发协作模型,是所有ƈ发协作的基础。可以这么说Q其他的q发协作都是供求关系模型的变U。生产者,消费者之间的供求关系可以单的 使用道来构造。让我们看两者之间的行ؓ模式Q? *生/消费模型Q消费者如果无消费对象Q就会阻塞直到有消费对象到达Q一个消费对象仅供一个消费者消贏V? *BlockingQueue: 如果队列为空Q则d操作会d直至队列有新的内容到达;队列中对象一旦被dQ将从队列中U走? 由此可见Q阻塞队列天然符合生?消费模型的供求行为模式。在前面展示condition的用法的时候,曄 用过生?消费者模型来举例。那个例子如果改用BlockingQueue来写的话十分简? <pre> ...<br /> BlockingQueue<String> q =new ArrayBlockingQueue<String> (10);<br /> ...<br /> public void supply () {<br /> q.put("product by "+Thread.currentThread().getId()+":"+(++productNo));<br /> }<br /> ...<br /> public void cunsume () {<br /> String product =q.take();<br /> System.out.println("consume product:"+product);<br /> }<br /> </pre> 从BlockingQueue也可以看出,它和UNIXpȝ下面的Pipe十分怼。所不同的不q是两点Q首先,pipe是进E间的,命名道甚至可以在非亲缘q程间用,而BlockingQueue 目前只是U程间的通信手段。当Ӟ׃java本n强大的动态类装蝲功能Q这个缺陷对javaE序之间的沟通限制ƈ不大。其ơ,pipe是基于字节流的,而BlockingQueue? Z对象的,q得BlockingQueue更加易用Q不q却让BlockingQueuel定了Java语言Qɘq一步成量本地q程通信工具的难度增大? <p>从前面对生/消费模型的行为方式可以看出,生/消费模型着重于规范消费者的行ؓ模式Q当消费速度过生速度的时候,消费者就会被d。而对于生产者的行ؓ则没? 规定。当生速度过消费速度Q生产者的行ؓ模式可以分ؓ以下几种Q? #当积压的产品辑ֈ一定数量时Q生产者被d #无论有多积压品,生者都不会被阻? #不能有Q何积压品,生者在当前产品未被消费之前Q会被阻? 对于产品来说Q也有不同的行ؓ模式 #产品只有在被生出来一D|间之后才能被消费(先花Ҏ间晾晑ֹQ? #不同cd的品被消费的优先不同(有钻石的话,黄金先放一边吧:))</p> <p>Ҏ生者行为模式的不同Concurrent包提供了不同的BlockingQueue的实? ||QueueU类||行ؓ描述 |ArrayBlockingQueue<e>|有限制的blocking queueQ积压的产品不得过制订数量 |DelayQueue<e>|产品只有生ZD|间之后,才能被消费,无限制的U压产品 |LinkedBlockingQueue<e>|同时支持有限制的blocking queueQ也能支持无限制的积压品(数量不能过Integer.MAX_VALUE) |PriorityBlockingQueue<e>|不同产品的被消费优先U不同,无限制的U压产品 |SynchronousQueue<e>|不允许积压?/e></e></e></e></e></p> <p>q些不同的行为模式中Q较为常见的除了ArrayBlockingQueue和LinkedBlockingQueue之外QPriorityBlockingQueue也非帔R要。D例来_如果我们利用BlockingQueue 来实C个邮件系l(著名的qmail是利用pipe技术构建的核心架构Q。我们知道邮件有不同的别,如果当前队列里有加急邮仉要处理的话,pȝ优先处理加急邮件? 我们以邮g传递ؓ例子Q说明PriorityBlockingQueue的用方法。(注:q里的这个邮件模型只是一个非常简陋的模型Q用来说明PriorityBlockingQueue的用方法而已Q? 和实际应用有很大的差距)</p> <p>首先Q我们需要了解邮件传递过E的基本模型。在q个单的邮g传送模型中涉及C列概? *MDA: Mail Deliver Agent, 负责接受指定用户的邮件? *MTA: Mail Transfer Agent, 负责接受q程传送过来的邮gQƈ其传送给收g人的MDA 它们和邮件用户之间的关系如下?/p> <p><img src="http://blogsite.3322.org/page/download_attach?name=email.gif&page_id=1929" alt="" /></p> 其中MTA使用Queue传送邮件给MDA。因此,不同的用户会使用不同的Mail Queue。下面是MailQueue的代? <pre>public class MailQueue<E> extends PriorityBlockingQueue<E>{<br /> public E take () throws InterruptedException {<br /> E ren =super.take();<br /> Utils._log("take:"+ren);<br /> return ren;<br /> }<br /> <br /> public void put (E o) {<br /> super.put(o);<br /> Utils._log("put:"+o);<br /> }<br /> }<br /> </pre> Z能够Ҏ收g人的Mail Address扑ֈ相应的Mail Queue, 使用一个MailQueueFactory来生MailQueue <pre>public class MailQueueFactory {<br /> //A ConcurrentHashMap is used here instead of Hashtable<br /> static ConcurrentHashMap<MailAccount,MailQueue<Mail>> mailQueues =<br /> new ConcurrentHashMap<MailAccount,MailQueue<Mail>>(); <br /> public static BlockingQueue<Mail> getMailQueue (MailDeliverer e) {<br /> return getMailQueue(e.getMailAccount());<br /> }<br /> <br /> public static BlockingQueue<Mail> getReceiveMailQueue (Mail m) {<br /> return getMailQueue (m.getReceiver());<br /> }<br /> <br /> public static BlockingQueue<Mail> getMailQueue (MailAccount e) {<br /> mailQueues.putIfAbsent (e,new MailQueue<Mail>());<br /> MailQueue<Mail> mailQ =mailQueues.get(e);<br /> <br /> return mailQ;<br /> }<br /> }<br /> </pre> 需要注意的是,我们在MailQueueFactory里面使用了ConcurrentHashMapQ而不是传l的Hashtable, 虽然Hashtable是thread-safeQ但是缺乏putIfAbsentq样? 原子函数Q如果不心设计的话Q会造成对同一个MailQueue重复初始化,从而导致死锁问题? 下面看Mail的定? <pre>public class Mail implements Comparable{<br /> public final static int emergencyMail =0;<br /> public final static int normalMail =1;<br /> <br /> static AtomicInteger serialCounter =new AtomicInteger(0);<br /> <br /> private int mailLevel;<br /> private int serialNumber =serialCounter.addAndGet(1);<br /> private MailAccount receiver =null;<br /> private MailAccount sender =null;<br /> private Date sendTime =new Date();<br /> <br /> public Mail (String from, String to, int level) {<br /> ...<br /> }<br /> <br /> //Get functions<br /> ...<br /> <br /> public int compareTo(Object o) {<br /> if (o instanceof Mail) {<br /> return compareTo ((Mail)o);<br /> }<br /> return 0;<br /> }<br /> <br /> public int compareTo (Mail o) {<br /> if (o.mailLevel==this.mailLevel) { //Same level, compare the serial no<br /> if (o.serialNumber==this.serialNumber)<br /> return 0;<br /> if (o.serialNumber>this.serialNumber)<br /> return -1;<br /> return 1;<br /> }<br /> if (this.mailLevel==emergencyMail) return -1;<br /> return 1;<br /> }<br /> //Other functions<br /> ...<br /> }<br /> </pre> q里值得注意的是AtomicInteger的用,它被用来做内部serialNumber的生。另外就是compareTo函数的用,PriorityBlockingQueue使用Comparable接口来判定元素的优先U别。这里所定义的优先如下Q? *如果邮gcd相同Q则序列号小的邮件有较大的优先 *如果邮gcd不同Q则emergencyMail有较大的优先U? 最后是Deliver Agent ?Transfer Agent的代? <pre>public class MailDeliverer {<br /> MailAccount mailAccount =null;<br /> <br /> public MailDeliverer (MailAccount account) {<br /> this.mailAccount =account;<br /> }<br /> <br /> public MailAccount getMailAccount() {<br /> return mailAccount;<br /> }<br /> <br /> public Mail retrieveMail () {<br /> Mail mail =null;<br /> while (mail==null) {<br /> try {<br /> mail =MailQueueFactory.getMailQueue(this).take();<br /> }catch (Exception e) {<br /> Utils._log("Encounter Exception",e);<br /> }<br /> }<br /> return mail;<br /> }<br /> }<br /> <br /> public class MailTransfer {<br /> private static MailTransfer instance =new MailTransfer ();<br /> private MailTransfer () { }<br /> <br /> public static MailTransfer getInstance () {<br /> return instance;<br /> }<br /> <br /> public void processMail (Mail m) {<br /> BlockingQueue mailQ =MailQueueFactory.getReceiveMailQueue(m);<br /> try {<br /> mailQ.put(m);<br /> } catch (InterruptedException e) {<br /> e.printStackTrace();<br /> }<br /> }<br /> }<br /> <br /> </pre> </span></span> <img src ="http://www.aygfsteel.com/java-blog/aggbug/156355.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/java-blog/" target="_blank">一步一步努力向上爬</a> 2007-10-27 16:23 <a href="http://www.aygfsteel.com/java-blog/articles/156355.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">躣</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ױ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǰ</a>| <a href="http://" target="_blank">פ</a>| <a href="http://" target="_blank">¯</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͼľ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ذ</a>| <a href="http://" target="_blank">Ԫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">пǰ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">͡</a>| <a href="http://" target="_blank">Զ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʳ</a>| <a href="http://" target="_blank">³ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank">Է</a>| <a href="http://" target="_blank">ָ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>