二、synchronized

1.共享、可变。

偷个懒,下面是《java并发编程实战》的一段:

当我第一次看到这段话的时候,确实有点晕。
对象的状态:成员变量、static变量以及其他依赖对象的域都是对象的状态。
如果一个对象是无状态的(既没有成员变量和static变量,也没有其他依赖对象的域),那么这个对象绝对是线程安全的。

共享:意味着对象的状态可以由多个线程同时访问。变量共享说明你的变量可以直接或者通过方法(例如:getXXX()方法)间接的访问。
可变:意味着变量的值在其生命周期内可以发生变化。
一个对象是否需要线程安全,取决于是否被多个线程访问。
如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误。

 

2.内置锁

java提供了一种内置锁机制来支持原子性:同步代码块(Synchronized Block)。同步代码块包括两部分:一个作为锁的对象引用,一个作为锁保护的代码块。以关键字synchronized修饰的方法,它的锁的对象引用就是方法调用所在的对象(哪个对象调用,就以哪个对象作为锁),而代码块为整个方法体。静态synchronized方法以Class对象作为锁。

synchronized(obj){ //以obj为锁对象
         //同步代码块
}

每个java都可以用做一个实现同步的锁,这些锁被称为内置锁或监视锁。线程进入同步代码块之前会自动获得锁,并且在退出同步代码块时自动释放锁,而无论是正常退出,还是抛异常退出。获得内置锁的唯一途径就是进入这个锁保护的同步代码块或方法。

每一个内置锁都是互斥锁,这就意味着最多只有一个线程能持有这种锁。

synchronized(c){
 ....    a同步代码块   
}

//当一个线程X走到这里时,如果已经有一个线程Y进入a同步代码块(或者b同步代码块)获得以c锁对象的内置锁,那么这个线程X就处于阻塞状态
synchronized(c){
 ....    a同步代码块  
}

重入:如果某个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。

class A {
  public synchronized void hehe(){
    System.out.println("A");    
  }
}

public class B extends A{
  public synchronized void hehe(){
   System.out.println("B");
   super.hehe();   //父类的hehe()方法也加了synchronized,这里是可重入的。
  }
}

 

posted @ 2016-06-23 20:04  伏天速  阅读(129)  评论(0编辑  收藏  举报