二synchronized
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二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,这里是可重入的。 } }
以上是关于二synchronized的主要内容,如果未能解决你的问题,请参考以下文章