注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

笑遍世界@网易博客

明天还会在路上……

 
 
 

日志

 
 
关于我

Stay hungry, stay foolish. 工作用脑,生活用心! 走过山重水复,必然迎来柳暗花明! 受苦的人没有悲观的权利,远征的人没有流泪的资格。 Live each day as if we should die tomorrow.

网易考拉推荐
GACHA精选
 
 

Java线程安全-基础知识  

2010-05-22 00:05:27|  分类: 编程技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
线程安全指的是当多个线程操作同一个数据段时,用相应的互斥机制,避免数据段中的数据错误。
每个线程尽量只访问别的线程不访问的变 量或内存,如果硬是要访问同一变量或内存的话,就要采用适当的互斥机制来避免由于线程切换而导致的不确定性。  
“线程安 全函数”就是当你在多线程程序中调用该函数,该函数本身不会出错,并且能得到正确的结果或处理——仅此而已!

四种方式    sychronized关键字
   1. sychronized method(){}
   2. sychronized (objectReference) {/*block*/}
   3. static synchronized method(){}
   4. sychronized(classname.class)

其中1 和2是代表锁当前对象,即一个对象就一个锁,3和4代表锁这个类,即这个类的锁
要注意的是sychronized method()不是锁这个函数,而是锁对象,即:如果这个类中有两个方法都是 sychronized,那么只要有两个线程共享一个该类的reference,每个调用这两个方法之一,不管是否同一个方法,都会用这个对象锁进行同 步。锁类的3和4类推,即该类的不同reference调用了sychronized区段的咚咚就会受类锁的控制

还有,如果两个函数调用的先后顺序不能被打断,那么可以有个专门的锁对象来完成这个任 务:
class MyLock
{
      synchronized getLock()
      {
          //####还没写完
      }
}

五个等级   参见effective java  Item 52 : Document thread safety
   1. immutable   不可变对象
   2. thread-safe 线程安全的,可以放心使用,如java.util.Timer
   3. conditionally thread-safe 条件线程安全的,如Vector和 Hashtable,一般是安全的,除非存在几个方法调用之间的顺序不能被打断,这时可以用额外的锁来完成
   4. thread-compatible 可以使用synchronized (objectReference)来协助完成对线程的调用
   5. thread-hostile 不安全的

死锁是一 个经典的多线程问题,因为不同的线程都在等待那些根本不可能被释放的锁,从而导致所有的工作都无法完成。假设有两个线程,分别代表两个饥饿的人,他们必须 共享刀叉并轮流吃饭。他们都需要获得两个锁:共享刀和共享叉的锁。假如线程 "A" 获得了刀,而线程 "B" 获得了叉。线程 A 就会进入阻塞状态来等待获得叉,而线程 B 则阻塞来等待 A 所拥有的刀。这只是人为设计的例子,但尽管在运行时很难探测到,这类情况却时常发生。虽然要探测或推敲各种情况是非常困难的,但只要按照下面几条规则去设 计系统,就能够避免死锁问题:
        * 让所有的线程按照同样的顺序获得一组锁。这种方法消除了 X 和 Y 的拥有者分别等待对方的资源的问题。
        * 将多个锁组成一组并放到同一个锁下。前面死锁的例子中,可以创建一个银器对象的锁。于是在获得刀或叉之前都必须获得这个银器的锁。
        * 将那些不会阻塞的可获得资源用变量标志出来。当某个线程获得银器对象的锁时,就可以通过检查变量来判断是否整个银器集合中的对象锁都可获得。如果是,它就 可以获得相关的锁,否则,就要释放掉银器这个锁并稍后再尝试。
        * 最重要的是,在编写代码前认真仔细地设计整个系统。多线程是困难的,在开始编程之前详细设计系统能够帮助你避免难以发现死锁的问题。
       
并发程序的多个线程之间的通讯通常是使用管道进行,jdk提供了两个管道类:PipedInpuStream和 PipedOutputStream,前者用于输入,后者用于输出。这两种管道应该是能够多次连接和关闭,在实现过程中,却发现它们在关闭后,不能重新建 立连接。经过仔细调试后,发现jdk的源代码在处理关闭时释放资源存在着缺陷,因此需要编写自己的管道类:MyPipedInputStream和 MyPipedOutputStream。这两个类直接从 InputStream和OutputStream继承而来,其成员方法与实现基本与PipedInputStream和 PipedOutputStream一致,只是在处理关闭时,将类中的成员变量的值恢复成未连接时的初始值。另外,原有的管道了提供的管道容量只有 1024个字节,在传输数据量较大时,可能会发生溢出,而在自己的管道类中可以任意设置管道容量。

一些参考资料:
http://dev.csdn.net/article/49/49689.shtm
http://www.ibm.com/developerworks/cn/java/j-rtj3/

  评论这张
 
阅读(578)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017