Final 可重入锁 安全发布

无状态对象(既不包含任何域,也不包含任何其他类中域的引用)一定是线程安全的。

Final

fianl域是不能修改的(但如果final域所引用的对象是可变的,那么这些被引用的对象是可变的)

除非需要可变域,否则应将其声明位final域。 


初始化:

	final int i = 0;	//在声明时就初始常量的值(每个对象的fianl常量都为一个值)

	public class Test{	//声明时未初始化,如果常量不通过构造方法或块初始化会报错

		final int i;

		{
			i=1;	//不可以再在构造函数里初始化i的值,因为块已经把常量初始化了(每个对象的fianl常量都为一个值)
		}

		Test(){
			i=1;	//通过构造方法初始化(如果有参构造器,每个对象的fianl常量可以是不同值)
		}
	}

	public class Test{	//静态类中初始化(每个对象的fianl常量都为一个值)

		static final int i;

		static{
			i=1;
		}
	}

可重入锁:为了避免死锁

当一个线程获取对象锁,需要再次获取这个对象锁:

	1. 一个对象中有多个同步方法

	2. 子类重写父类同步方法:

		super不是指父类对象,而是一个引用,引用从父类继承来的方法。

		super.父类方法,通过super引用调用从父类继承来的方法,锁对象仍然是子类对象。


public class aaa{
    public static void main(String[] args) {
        ccc ccc = new ccc();
        ccc.dothing();
    }
}

class bbb{
    public void dothing(){
        System.out.println("父类:"+this.toString());
    }
}

class ccc extends bbb{
    @Override
    public void dothing() {
        super.dothing();
        System.out.println("super:"+super.toString());
        System.out.println("子类:"+this.toString());
    }
}

输出:
	父类:ccc@62043840
	super:ccc@62043840
	子类:ccc@62043840

安全发布

不安全发布(多线程问题):

	public Holder holder;

	public void init() {
		holder = new Holder(42);
	}

	由于可见性问题,其他线程看到的Holder对象可能处于不一致状态。


安全发布(保证可见性):

	静态初始化器中初始化对象引用(public static Holder holder = new Holder(24);):最简单,最安全

	将对象引用保存在volatile域或者AtomicReferance对象中

	对象引用保存在final域中

	对象引用保存在由锁保护的域中


安全发布容器:
	ConcurrentMap
	CopyOnWriteArrayList
	BlockingQueue


可变对象:
	不仅需要安全发布,并且必须是线程安全的。

	解决:
		线程封闭:ThreadLocal
		只读共享:CopyOnWriteArrayList 和 CopyOnWriteArraySet
		同步:synchronizer
		保护对象:AtomicReferance
原文地址:https://www.cnblogs.com/loveer/p/11741838.html