﻿<?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-一个人编程-随笔分类-设计模式</title><link>http://www.blogjava.net/linli/category/44445.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 10 Oct 2014 06:02:04 GMT</lastBuildDate><pubDate>Fri, 10 Oct 2014 06:02:04 GMT</pubDate><ttl>60</ttl><item><title>JAVA并发编程的理解</title><link>http://www.blogjava.net/linli/archive/2014/10/10/418583.html</link><dc:creator>xy.lin</dc:creator><author>xy.lin</author><pubDate>Fri, 10 Oct 2014 05:41:00 GMT</pubDate><guid>http://www.blogjava.net/linli/archive/2014/10/10/418583.html</guid><wfw:comment>http://www.blogjava.net/linli/comments/418583.html</wfw:comment><comments>http://www.blogjava.net/linli/archive/2014/10/10/418583.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/linli/comments/commentRss/418583.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/linli/services/trackbacks/418583.html</trackback:ping><description><![CDATA[<div>并发编程时，必须考虑安全性问题，即线程安全，所谓线程安全就是可以同时被多个线程调用，调用者无须额外的操作，程序也不会出现错误的结果。</div><div>要使程序是线程安全的，必须考虑以下2点：</div><div><ol><li>是否存在竞态条件，常见的是那些先检查后执行的操作行为，它的正确结果取决于运气。避免错误结果的方法是保证操作的原子性，通常使用加锁，也有一些原子变量类可以达到目的。</li><li>对象状态在内存中是否可见，即当一个线程修改了对象的状态后，其他线程不一定看到修改后的状态。保证其他线程总是能看到最新状态的方法有2种：一种是加锁，另一种是使用volatile变量。</li></ol></div><div>于是得出几个结论：</div><div><ol><li>加锁机制可保证可见性和原子性，所以能保证线程安全；</li><li>原子变量可保证原子性，但不能保证可见性，所以不能保证线程安全；</li><li>volatile变量能保证可见性，但不能保证原子性，所以不能保证线程安全；</li><li>volatile的原子变量能保证线程安全。</li></ol></div><div>除此之外，还有一些对象一定是线程安全的：</div><div><ol><li>无状态对象；</li><li>不可变对象。</li></ol></div><div></div><div>但是加锁机制会产生活跃性问题，活跃性问题关注正确的行为是否一定会发生，主要有死锁问题。<br />死锁简单来讲是这样的：线程A持有锁L并想获得锁M，同时线程B持有锁M并想获得锁L，这时线程A和B都永久阻塞。</div><div>避免死锁的关键是要保证每个线程获取锁的顺序必须相同，如上面线程A和B获取锁的顺序如果都是先获取锁L再获取锁M，就不会发生死锁问题。</div><div>当持有锁时调用外部方法，会很难分析获取锁的顺序，要尽量避免。</div><div></div><div>编码参考：</div><div><ol><li>将所有可变状态都封装在对象内部，并通过对象的内置锁对所有访问可变状态的代码进行同步；</li><li>扩展线程安全的容器类时，在新类中委托容器类的其他方法，使用新锁，不要关心原来的容器类是否线程安全。</li></ol></div><div></div><div>参考资料：</div><div>《JAVA并发编程实战》</div><div></div><img src ="http://www.blogjava.net/linli/aggbug/418583.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/linli/" target="_blank">xy.lin</a> 2014-10-10 13:41 <a href="http://www.blogjava.net/linli/archive/2014/10/10/418583.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计原则</title><link>http://www.blogjava.net/linli/archive/2010/03/30/316894.html</link><dc:creator>xy.lin</dc:creator><author>xy.lin</author><pubDate>Tue, 30 Mar 2010 00:44:00 GMT</pubDate><guid>http://www.blogjava.net/linli/archive/2010/03/30/316894.html</guid><wfw:comment>http://www.blogjava.net/linli/comments/316894.html</wfw:comment><comments>http://www.blogjava.net/linli/archive/2010/03/30/316894.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/linli/comments/commentRss/316894.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/linli/services/trackbacks/316894.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一个软件实体，应当对扩展开放，对修改关闭。<br>要求一个软件系统可以在不修改原有代码的情况下，通过扩展达到增强其功能的目的。&nbsp;&nbsp;<a href='http://www.blogjava.net/linli/archive/2010/03/30/316894.html'>阅读全文</a><img src ="http://www.blogjava.net/linli/aggbug/316894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/linli/" target="_blank">xy.lin</a> 2010-03-30 08:44 <a href="http://www.blogjava.net/linli/archive/2010/03/30/316894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>