﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-kxbin-文章分类-java基础</title><link>http://www.blogjava.net/kxbin/category/40783.html</link><description>创出一片天地</description><language>zh-cn</language><lastBuildDate>Wed, 21 Mar 2012 22:08:09 GMT</lastBuildDate><pubDate>Wed, 21 Mar 2012 22:08:09 GMT</pubDate><ttl>60</ttl><item><title>java synchronized详解(转)</title><link>http://www.blogjava.net/kxbin/articles/371112.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Fri, 02 Mar 2012 01:22:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/371112.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/371112.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/371112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/371112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/371112.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java语言的关键字，当它用来修饰一个方法或者一个代码块的时候，能够保证在同一时刻最多只有一个线程执行该段代码。&nbsp;&nbsp;&nbsp;&nbsp; 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时，一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。&nbsp;&nbsp;&nbsp;&...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/371112.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/371112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2012-03-02 09:22 <a href="http://www.blogjava.net/kxbin/articles/371112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Set与List之间转化</title><link>http://www.blogjava.net/kxbin/articles/366982.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 22 Dec 2011 01:13:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/366982.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/366982.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/366982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/366982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/366982.html</trackback:ping><description><![CDATA[<div><span style="font-family: simsun; font-size: 14px; line-height: 23px; background-color: #ffffff; ">List list = new ArrayList(set);</span><br style="font-family: simsun; font-size: 14px; line-height: 23px; text-align: left; background-color: #ffffff; " /><span style="font-family: simsun; font-size: 14px; line-height: 23px; text-align: left; background-color: #ffffff; ">Set set = new HashSet(list);<br /></span><div><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">//</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">但是有一点,转换当中可能要丢失数据,尤其是从list转换到set的时候,因为set不能有重复数据 </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">//</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">还有转换到set之后,他们原先在list上的顺序就没了,<br /></span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; "> </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #0000ff; ">public</span> <span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #0000ff; ">class</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; "> Csdn {     <br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #0000ff; ">public</span> <span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #0000ff; ">static</span> <span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #0000ff; ">void</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; "> main(String[] args) {        <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&lt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">String</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&gt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; "> list </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">=</span> <span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #0000ff; ">new</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; "> ArrayList</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&lt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">String</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&gt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">();         <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collections.addAll(list, </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">"</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">zhao</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">"</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">,</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">"</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">long</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">"</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">,</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">"</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">ri</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">"</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">);</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">//</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">填充</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; "> </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">        <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&lt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">String</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&gt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; "> set</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">=n</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #0000ff; ">ew</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; "> HashSet</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&lt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">String</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">&gt;</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">();         <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set.addAll(list);</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">//</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">给set填充</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; "> </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">        <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.clear();</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">//</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">清空list，不然下次把set元素加入此list的时候是在原来的基础上追加元素的</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; "> </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">        <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.addAll(set);</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">//</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; ">把set的</span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; color: #008000; "> </span><span style="line-height: 18px; font-family: monospace; font-size: 12px; white-space: pre; ">    <br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /> }</span></div></div><img src ="http://www.blogjava.net/kxbin/aggbug/366982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-12-22 09:13 <a href="http://www.blogjava.net/kxbin/articles/366982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA反射机制（转）</title><link>http://www.blogjava.net/kxbin/articles/365690.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Tue, 06 Dec 2011 09:14:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/365690.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/365690.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/365690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/365690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/365690.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、什么是反射：反射的概念是由Smith在1982年首次提出的，主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。最近，反射机制也被应用到了视窗系统、操作...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/365690.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/365690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-12-06 17:14 <a href="http://www.blogjava.net/kxbin/articles/365690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java synchronized详解</title><link>http://www.blogjava.net/kxbin/articles/365636.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Tue, 06 Dec 2011 00:43:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/365636.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/365636.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/365636.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/365636.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/365636.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java语言的关键字，当它用来修饰一个方法或者一个代码块的时候，能够保证在同一时刻最多只有一个线程执行该段代码。&nbsp;&nbsp;&nbsp;&nbsp; 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时，一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。&nbsp;&nbsp;&nbsp;&...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/365636.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/365636.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-12-06 08:43 <a href="http://www.blogjava.net/kxbin/articles/365636.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索并发编程（七）------分布式环境中并发问题（转）</title><link>http://www.blogjava.net/kxbin/articles/361160.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 13 Oct 2011 08:05:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/361160.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/361160.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/361160.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/361160.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/361160.html</trackback:ping><description><![CDATA[<div><span style="color: #333333; font-family: Arial; font-size: 17px; line-height: 25px; "><p>在分布式环境中，处理并发问题就没办法通过操作系统和JVM的工具来解决，那么在分布式环境中，可以采取一下策略和方式来处理：</p><ul><li>避免并发</li><li>时间戳</li><li>串行化</li><li>数据库</li><li>行锁</li><li>统一触发途径</li></ul><p><strong>避免并发</strong></p><p>在分布式环境中，如果存在并发问题，那么很难通过技术去解决，或者解决的代价很大，所以我们首先要想想是不是可以通过某些策略和业务设计来避免并发。比如通过合理的时间调度，避开共享资源的存取冲突。另外，在并行任务设计上可以通过适当的策略，保证任务与任务之间不存在共享资源，比如在以前博文中提到的例子，我们需要用多线程或分布式集群来计算一堆客户的相关统计值，由于客户的统计值是共享数据，因此会有并发潜在可能。但从业务上我们可以分析出客户与客户之间 数据是不共享的，因此可以设计一个规则来保证一个客户的计算工作和数据访问只会被一个线程或一台工作机完成，而不是把一个客户的计算工作分配给多个线程去 完成。这种规则很容易设计，例如可以采用hash算法。</p><p><strong>时间戳</strong></p><p>分布式环境中并发是没法保证时序的，无论是通过远程接口的同步调用或异步消息，因此很容易造成某些对时序性有要求的业务在高并发时产生错误。比如系统A需要把某个值的变更同步到系统B，由于通知的时序问题会导致一个过期的值覆盖了有效值。对于这个问题，常用的办法就是采用时间戳的方式，每次系统A发送变更给系统B的时候需要带上一个能标示时序的时间戳，系统B接到通知后会拿时间戳与存在的时间戳比较，只有当通知的时间戳大于存在的时间戳，才做更新。这种方式比较简单，但关键在于调用方一般要保证时间戳的时序有效性。</p><p><strong>串行化</strong></p><p>有的时候可以通过串行化可能产生并发问题操作，牺牲性能和扩展性，来满足对数据一致性的要求。比如分布式消息系统就没法保证消息的有序性，但可以通过变分布式消息系统为单一系统就可以保证消息的有序性了。另外，当接收方没法处理调用有序性，可以通过一个队列先把调用信息缓存起来，然后再串行地处理这些调用。</p><p><strong>数据库</strong></p><p>分布式环境中的共享资源不能通过Java里同步方法或加锁来保证线程安全，但数据库是分布式各服务器的共享点，可以通过数据库的高可靠一致性机制来满足需求。比如，可以通过唯一性索引来解决并发过程中重复数据的生产或重复任务的执行；另外有些更新计算操作也尽量通过sql来完成，因为在程序段计算好后再去更新就有可能发生脏复写问题，但通过一条sql来完成计算和更新就可以通过数据库的锁机制来保证update操作的一致性。</p><p><strong>行锁</strong></p><p>有的事务比较复杂，无法通过一条sql解决问题，并且有存在并发问题，这时就需要通过行锁来解决，一般行锁可以通过以下方式来实现：</p><ul><li>对于Oracle数据库，可以采用select ... for update方式。这种方式会有潜在的危险，就是如果没有commit就会造成这行数据被锁住，其他有涉及到这行数据的任务都会被挂起，应该谨慎使用</li><li>在表里添加一个标示锁的字段，每次操作前，先通过update这个锁字段来完成类似竞争锁的操作，操作完成后在update锁字段复位，标示已归还锁。这种方式比较安全，不好的地方在于这些update锁字段的操作就是额外的性能消耗</li></ul><p><strong>统一触发途径</strong></p><p>当一个数据可能会被多个触发点或多个业务涉及到，就有并发问题产生的隐患，因此可以通过前期架构和业务设计，尽量统一触发途径，触发途径少了一是减少并发的可能，也有利于对于并发问题的分析和判断。</p></span></div><img src ="http://www.blogjava.net/kxbin/aggbug/361160.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-10-13 16:05 <a href="http://www.blogjava.net/kxbin/articles/361160.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索并发编程（五）------Java多线程开发技巧（转）</title><link>http://www.blogjava.net/kxbin/articles/361158.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 13 Oct 2011 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/361158.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/361158.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/361158.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/361158.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/361158.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 很多开发者谈到Java多线程开发，仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面，对于线程的管理和控制却不够深入，通过读《Java并发编程实践》了解到了很多不为我知但又非常重要的细节，今日整理如下。不应用线程池的缺点有些开发者图省事，遇到需要多线程处理的地方，直接new Thread(...).start()，对于一般场景是没问题的，但如果是在并发请...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/361158.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/361158.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-10-13 16:04 <a href="http://www.blogjava.net/kxbin/articles/361158.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索并发编程（六）------Java多线程性能优化（转）</title><link>http://www.blogjava.net/kxbin/articles/361159.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 13 Oct 2011 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/361159.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/361159.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/361159.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/361159.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/361159.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 大家使用多线程无非是为了提高性能，但如果多线程使用不当，不但性能提升不明显，而且会使得资源消耗更大。下面列举一下可能会造成多线程性能问题的点：死锁过多串行化过多锁竞争切换上下文内存同步下面分别解析以上性能隐患死锁关于死锁，我们在学习操作系统的时候就知道它产生的原因和危害，这里就不从原理上去累述了，可以从下面的代码和图示重温一下死锁产生的原因：&nbsp;public&nbsp;class&nbsp...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/361159.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/361159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-10-13 16:04 <a href="http://www.blogjava.net/kxbin/articles/361159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索并发编程（四）------Java并发工具（转）</title><link>http://www.blogjava.net/kxbin/articles/361157.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 13 Oct 2011 08:02:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/361157.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/361157.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/361157.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/361157.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/361157.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 基于线程安全的一些原则来编程当然可以避免并发问题，但不是所有人都能写出高质量的线程安全的代码，并且如果代码里到处都是线程安全的控制也极大地影响了代码可读性和可维护性。因此，Java平台为了解决这个问题，提供了很多线程安全的类和并发工具，通过这些类和工具就能更简便地写线程安全的代码。归纳一下有以下几种：同步容器类并发容器类生产者和消费者模式阻塞和可中断方法Synchronizer这些类和方法的使用都...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/361157.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/361157.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-10-13 16:02 <a href="http://www.blogjava.net/kxbin/articles/361157.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索并发编程（三）------Java存储模型和共享对象（转）</title><link>http://www.blogjava.net/kxbin/articles/361156.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 13 Oct 2011 07:47:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/361156.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/361156.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/361156.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/361156.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/361156.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 很多程序员对一个共享变量初始化要注意可见性和安全发布（安全地构建一个对象，并其他线程能正确访问）等问题不是很理解，认为Java是一个屏蔽内存细节的平台，连对象回收都不需要关心，因此谈到可见性和安全发布大多不知所云。其实关键在于对Java存储模型，可见性和安全发布的问题是起源于Java的存储结构。Java存储模型原理有很多书和文章都讲解过Java存储模型，其中一个图很清晰地说明了其存储结构：由上图可...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/361156.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/361156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-10-13 15:47 <a href="http://www.blogjava.net/kxbin/articles/361156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索并发编程（二）------写线程安全的Java代码（转）</title><link>http://www.blogjava.net/kxbin/articles/361155.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 13 Oct 2011 07:37:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/361155.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/361155.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/361155.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/361155.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/361155.html</trackback:ping><description><![CDATA[<div><span style="color: #333333; font-family: Arial; font-size: 17px; line-height: 25px; "><p>在写Java程序的时候，何时需要进行并发控制，关键在于判断这段程序或这个类是否是线程安全的。</p><p>当多个线程访问一个类时，如果不用考虑这些线程在运行时环境下的调度和交替执行，并且不需要额外的同步，这个类的行为仍然是正确的，那么称这个类是线程安全的。我们设计类就是要在有潜在并发问题存在情况下，设计线程安全的类。线程安全的类可以通过以下手段来满足：</p><ul><li>不跨线程共享变量</li><li>使状态变量为不可变的</li><li>在任何访问状态变量的时候使用同步。</li><li>每个共享的可变变量都需要由唯一一个确定的锁保护。</li></ul><p><strong>满足线程安全的一些思路</strong></p><p><strong>1）从源头避免并发问题</strong></p><p>很多开发者一想到有并发的可能就通过底层技术来解决问题，其实往往可以通过上层的架构设计和业务分析来避免并发场景。比如我们需要用多线程或分布式集群来计算一堆客户的相关统计值，由于客户的统计值是共享数据，因此会有并发潜在可能。但从业务上我们可以分析出客户与客户之间数据是不共享的，因此可以设计一个规则来保证一个客户的计算工作和数据访问只会被一个线程或一台工作机完成，而不是把一个客户的计算工作分配给多个线程去完成。这种规则很容易设计。当你从源头就避免了并发问题的可能，下面的工作就完全可以不用担心线程安全问题。</p><p><strong>2）无状态就是线程安全</strong></p><p>多线程编程或者分布式编程最忌讳有状态，一有状态就不但限制了其横向扩展能力，也是产生并发问题的起源。当你设计的类是无状态的，那么它永远都是线程安全的。因此在设计阶段需要考虑如何用无状态的类来满足你的业务需求</p><p><strong>3）分清原子性操作和复合操作</strong></p><p>所谓原子性，是说一个操作不会被其他线程打断，能保证其从开始到结束独享资源连续执行完这一操作。如果所有程序块都是原子性的，那么就不存在任何并发问题。而很多看上去像是原子性的操作正式并发问题高灾区。比如所熟知的计数器（count++）和check-then-act，这些都是很容易被忽视的，例如大家所常用的惰性初始化模式，以下代码就不是线程安全的：</p><p>&nbsp;</p><div nogutter=""  bg_java:nogutter:nocontrols"="" style="font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #e7e5dc; width: 688px; overflow-x: auto; overflow-y: auto; margin-top: 18px !important; margin-right: 0px !important; margin-bottom: 18px !important; margin-left: 0px !important; padding-top: 1px; "><div style="padding-left: 0px; "></div><ol start="1" style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 1px !important; margin-left: 0px !important; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; list-style-type: none !important; list-style-position: initial !important; list-style-image: initial !important; background-color: #ffffff; color: #5c5c5c; "><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #ffffff; color: inherit; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #646464; background-color: inherit; ">@NotThreadSafe</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;&nbsp;</span></span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #f8f8f8; color: #5c5c5c; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">public</span>&nbsp;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">class</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;LazyInitRace&nbsp;{&nbsp;&nbsp;</span></span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #ffffff; color: inherit; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;&nbsp;&nbsp;&nbsp;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">private</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;ExpensiveObject&nbsp;instance&nbsp;=&nbsp;</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">null</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">;&nbsp;&nbsp;</span></span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #f8f8f8; color: #5c5c5c; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;&nbsp;&nbsp;&nbsp;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">public</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;ExpensiveObject&nbsp;getInstance()&nbsp;{&nbsp;&nbsp;</span></span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #ffffff; color: inherit; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">if</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;(instance&nbsp;==&nbsp;</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">null</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">)&nbsp;&nbsp;</span></span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #f8f8f8; color: #5c5c5c; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance&nbsp;=&nbsp;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">new</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;ExpensiveObject();&nbsp;&nbsp;</span></span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #ffffff; color: inherit; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: #006699; background-color: inherit; font-weight: bold; ">return</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;instance;&nbsp;&nbsp;</span></span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #f8f8f8; color: #5c5c5c; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-width: initial; border-color: initial; list-style-type: none !important; list-style-image: initial !important; list-style-position: initial !important; border-left-width: 0px; background-color: #ffffff; color: inherit; line-height: 25px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-style: initial; border-color: initial; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; color: black; background-color: inherit; ">}&nbsp;&nbsp;</span></li></ol></div><p>&nbsp;</p><p>这段代码具体问题在于没有认识到if(instance==null)和instance = new ExpensiveObject();是两条语句，放在一起就不是原子性的，就有可能当一个线程执行完if(instance==null)后会被中断，另一个线程也去执行if(instance==null)，这次两个线程都会执行后面的instance = new ExpensiveObject();这也是这个程序所不希望发生的。</p><p>虽然check-then-act从表面上看很简单，但却普遍存在与我们日常的开发中，特别是在数据库存取这一块。比如我们需要在数据库里存一个客户的统计值，当统计值不存在时初始化，当存在时就去更新。如果不把这组逻辑设计为原子性的就很有可能产生出两条这个客户的统计值。</p><p>在单机环境下处理这个问题还算容易，通过锁或者同步来把这组复合操作变为原子操作，但在分布式环境下就不适用了。一般情况下是通过在数据库端做文章，比如通过唯一性索引或者悲观锁来保障其数据一致性。当然任何方案都是有代价的，这就需要具体情况下来权衡。</p><p>另外，java1.5以后提供了一套提供原子性操作的类，有兴趣的可以研究一下它是如何在软件层面保证原子性的。</p><p><strong>4）锁的合理使用</strong></p><p>大家都知道可以用锁来解决并发问题，但在具体使用上还有很多讲究，比如：</p><ul><li>每个共享的可变变量都需要由一个个确定的锁保护。</li><li>一旦使用了锁，就意味着这段代码的执行就丧失了操作系统多道程序的特性，会在一定程度上影响性能</li><li>锁不能解决在分布式环境共享变量的并发问题</li></ul></span></div><img src ="http://www.blogjava.net/kxbin/aggbug/361155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-10-13 15:37 <a href="http://www.blogjava.net/kxbin/articles/361155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探索并发编程（一）------操作系统篇（转）</title><link>http://www.blogjava.net/kxbin/articles/361153.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Thu, 13 Oct 2011 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/361153.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/361153.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/361153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/361153.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/361153.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在多线程、多处理器甚至是分布式环境的编程时代，并发是一个不可回避的问题，很多程序员一碰到并发二字头皮就发麻，也包括我。既然并发问题摆在面前一个到无法回避的坎，倒不如拥抱它，把它搞清楚，决心花一定的时间从操作系统底层原理到Java的基础编程再到分布式环境等几个方面深入探索并发问题。先就从原理开始吧。并发产生的原因虽然从直观效果上，处理器是并行处理多项任务，但本质上一个处理器在某个时间点只能处理一个任...&nbsp;&nbsp;<a href='http://www.blogjava.net/kxbin/articles/361153.html'>阅读全文</a><img src ="http://www.blogjava.net/kxbin/aggbug/361153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-10-13 15:26 <a href="http://www.blogjava.net/kxbin/articles/361153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>连接数据库的方法（从属性文件中读取）</title><link>http://www.blogjava.net/kxbin/articles/358629.html</link><dc:creator>kxbin</dc:creator><author>kxbin</author><pubDate>Wed, 14 Sep 2011 08:47:00 GMT</pubDate><guid>http://www.blogjava.net/kxbin/articles/358629.html</guid><wfw:comment>http://www.blogjava.net/kxbin/comments/358629.html</wfw:comment><comments>http://www.blogjava.net/kxbin/articles/358629.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kxbin/comments/commentRss/358629.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kxbin/services/trackbacks/358629.html</trackback:ping><description><![CDATA[1.属性文件的内容（以键值对的形式保存）：<br /><div><div>url=jdbc\:oracle\:thin\:@localhost\:1521\:orcl</div><div>user.name=root</div><div>user.password=root</div><div>driver.class=oracle.jdbc.driver.OracleDriver<br />2.读取属性文件<br />&nbsp;package com.srg.china.db;</div><div><div>import java.io.IOException;</div><div>import java.io.InputStream;</div><div>import java.sql.Connection;</div><div>import java.sql.DriverManager;</div><div>import java.sql.SQLException;</div><div>import java.util.Properties;</div><div></div><div>import org.apache.log4j.Logger;</div><div>/**</div><div>&nbsp;* 程序功能：取得数据库的连接</div><div>&nbsp;* @author Administrator</div><div>&nbsp;*</div><div>&nbsp;*/</div><div>public class ChinaLogin {</div><div><span style="white-space:pre">	</span>private static Logger log=Logger.getLogger(ChinaLogin.class);</div><div><span style="white-space:pre">	</span>static Properties prop=null;</div><div><span style="white-space:pre">	</span>static String driver;</div><div><span style="white-space:pre">	</span>static String url;</div><div><span style="white-space:pre">	</span>static String user;</div><div><span style="white-space:pre">	</span>static String pwd;</div><div><span style="white-space:pre">	</span>static{</div><div><span style="white-space:pre">		</span>InputStream ins=null;</div><div><span style="white-space:pre">		</span>prop=new Properties();</div><div><span style="white-space:pre">		</span>ins=ChinaLogin.class.getResourceAsStream("./db.properties");</div><div><span style="white-space:pre">		</span>if(null == ins){</div><div><span style="white-space:pre">			</span>log.debug("文件不存在");</div><div><span style="white-space:pre">		</span>}else{</div><div><span style="white-space:pre">			</span>try {</div><div><span style="white-space:pre">				</span>prop.load(ins);</div><div><span style="white-space:pre">				</span>driver=prop.getProperty("driver.class");</div><div><span style="white-space:pre">				</span>url=prop.getProperty("url");</div><div><span style="white-space:pre">				</span>user=prop.getProperty("user.name");</div><div><span style="white-space:pre">				</span>pwd=prop.getProperty("user.password");</div><div><span style="white-space:pre">			</span>} catch (IOException e) {</div><div><span style="white-space:pre">				</span>log.debug(e.getMessage());</div><div><span style="white-space:pre">			</span>}</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">	</span>}</div><div>//<span style="white-space:pre">	</span>取得数据库的连接</div><div><span style="white-space:pre">	</span>public static Connection getConnection(){</div><div><span style="white-space:pre">		</span>Connection conn=null;</div><div><span style="white-space:pre">		</span></div><div><span style="white-space:pre">		</span>try {</div><div><span style="white-space:pre">			</span>Class.forName(driver);</div><div><span style="white-space:pre">			</span>conn=DriverManager.getConnection(url,user,pwd);</div><div><span style="white-space:pre">		</span>} catch (ClassNotFoundException e) {</div><div><span style="white-space:pre">			</span>log.debug("注册失败"+e.getMessage());</div><div><span style="white-space:pre">		</span>} catch (SQLException e) {</div><div><span style="white-space:pre">			</span>log.debug("连接失败"+e.getMessage());</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">		</span></div><div><span style="white-space:pre">		</span>return conn;</div><div><span style="white-space:pre">	</span>}</div><div><span style="white-space:pre">	</span></div><div>//<span style="white-space:pre">	</span>测试</div><div><span style="white-space:pre">	</span>/*</div><div><span style="white-space:pre">	</span>public static void main(String[] args){</div><div><span style="white-space:pre">		</span>Connection conn=null;</div><div><span style="white-space:pre">		c</span>onn=ChinaLogin.getConnection();</div><div><span style="white-space:pre">		</span>if(conn!=null){</div><div><span style="white-space:pre">			</span>log.debug("成功");</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">	</span>}</div><div><span style="white-space:pre">	</span>*/</div><div>}</div></div><div></div></div><div></div><img src ="http://www.blogjava.net/kxbin/aggbug/358629.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kxbin/" target="_blank">kxbin</a> 2011-09-14 16:47 <a href="http://www.blogjava.net/kxbin/articles/358629.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>