Java线程安全

来源:互联网 发布:宏景hr软件 编辑:程序博客网 时间:2024/05/02 07:54

这里的线程安全,限定于多个线程之间存在共享数据访问这个前提,如果一段代码不会与其它线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它都没有区别。

线程安全的实现方法

1. 互斥同步

同步是指在多个线程并发访问共享数据时,保证共享数据在某一时刻只被一个线程使用。

互斥是实现同步的一种手段,临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)都是主要的互斥实现方式。因此,互斥是因,同步是果;

在Java中,最基本的互斥同步手段就是synchronized关键字,synchronized关键字经过编译后,会在同步块的前后分别形成monitorenter、monitorexit这两个字节码指令。

根据虚拟机规范,在执行monitorenter指令时,首先要尝试获取对象锁。如果这个对象没被锁定,或者当前线程已经拥有了那个对象的锁,把锁的计数器加1,在执行monitorexit指令时,把锁的计数器减1,当计数器为0时,锁就被释放。如果获取对象锁失败,那么当前线程就要阻塞等待,直到对象锁被另一个线程释放为止。

Java的线程是映射到操作系统的原生线程之上的,如果要阻塞或要唤醒一个线程,都需要操作系统来帮忙,这就需要从用户态转换到核心态,状态转移需要耗费很多的处理器时间。所以synchronized是Java中的一个重量级操作,应该在确实有必要的情况下才使用,而虚拟机也会进行一些优化,比如在通知操作系统阻塞线程之前加入一段自旋等待过程,避免频繁地切入到核心态。

synchronized锁是不公平的,即在锁被释放时,任何一个等待锁的线程都有机会获得锁。

0 0
原创粉丝点击