java线程安全实现_实现Java线程安全

一个类如果想要满足线程安全的条件:

每个线程都能正常的执行原子操作,保证得到正确的结果

这个类的对象可以同时被多个线程安全的访问

在每个线程的原子操作都完成后,对象处于合理的状态

一般情况下不可变类总是线程安全的,因为他的对象的状态始终不会改变,任何线程只能读取他的状态,而不能改变他的状态,例如String类就是一个不可变类,因为String类在我们的代码中使用的实在是太多了,如果设计成可变类后果可想而知……对于那些可变类,如果想要保证它的们的线程安全,就要保证对于他们的原子操作进行同步。

我们常说StirngBuffer是线程安全的,StringBuilder是线程不安全的,为什么呢?因为在StringBuffer类中大量使用了同步,以下只是一小部分方法,方法都用synchronized关键字修饰,做到同步

135918175fb693300ea9991a0f5d4006.png

但是大量运用同步可能对性能造成影响,同步的意思好比大家一起排队做某件事,举个例子i,有十个人去吃饭,但是饭店的座位只有一个,只能一个一个吃,第一个人先吃,这样依次下去,那么第十个人要等到前面九个人都吃完了才能吃饭,想想是不是很委屈。对可变类实现同步往往都会降低并发性能,为了减少带来的影响,我们可以采取下面的措施:

只对额能导致资源竞争的代码进行同步处理,对于那些没有资源竞争的代码不进行处理,例如我们在对一个属性提供set和get方法的时候,试着只提供get方法获取值,不提供set方法修改值,这样虽然好多个线程同时访问,也不会造成数据的错误和资源的竞争。

对于多线程环境下我们提供一个运行方式,对于单线程环境下提供一个运行方式。一个类提供两种实现方式,在单线程运行环境下采用微进行同步实现的代码,对于对线程运行环境下采用进行同步处理的代码,避免一刀切。这里有个很好的例子,Map,Set,List这三个集合类都是线程不安全的,在多线程环境下怎么办呢?Collections类提供了很好的解决办法,他提供了返回这些集合同步版本的静态内部类,并在类中重写了集合中所有有资源竞争的方法,加了synchronized关键字进行同步处理

b629ac5ecd665b3777d106473aaa8fca.png

SynchronizedCollection和三个集合一样,也是实现了同步的方法,看代码:

public static List synchronizedList(List list) {

return(list instanceofRandomAccess ?

newSynchronizedRandomAccessList<>(list) :

newSynchronizedList<>(list));

}

static List synchronizedList(List list, Object mutex) {

return(list instanceofRandomAccess ?

newSynchronizedRandomAccessList<>(list, mutex) :

newSynchronizedList<>(list, mutex));

}

/***@serialinclude*/static classSynchronizedList

extendsSynchronizedCollection

implementsList {

private static final longserialVersionUID= -7754090372962971524L;

finalList list;

SynchronizedList(List list) {

super(list);

this.list= list;

}

SynchronizedList(List list, Object mutex) {

super(list, mutex);

this.list= list;

}

public booleanequals(Object o) {

if(this== o)

return true;

synchronized(mutex) {returnlist.equals(o);}

}

public inthashCode() {

synchronized(mutex) {returnlist.hashCode();}

}

publicEget(intindex) {

synchronized(mutex) {returnlist.get(index);}

}

publicEset(intindex, Eelement) {

synchronized(mutex) {returnlist.set(index, element);}

}

public voidadd(intindex, Eelement) {

synchronized(mutex) {list.add(index, element);}

}

publicEremove(intindex) {

synchronized(mutex) {returnlist.remove(index);}

}

public intindexOf(Object o) {

synchronized(mutex) {returnlist.indexOf(o);}

}

public intlastIndexOf(Object o) {

synchronized(mutex) {returnlist.lastIndexOf(o);}

}

public booleanaddAll(intindex, Collection extendsE> c) {

synchronized(mutex) {returnlist.addAll(index, c);}

}

publicListIterator listIterator() {

returnlist.listIterator(); // Must be manually synched by user}

publicListIterator listIterator(intindex) {

returnlist.listIterator(index); // Must be manually synched by user}

publicList subList(intfromIndex, inttoIndex) {

synchronized(mutex) {

return newSynchronizedList<>(list.subList(fromIndex, toIndex),

mutex);

}

}

public static Set synchronizedSet(Set s) {

return newSynchronizedSet<>(s);

}

static Set synchronizedSet(Set s, Object mutex) {

return newSynchronizedSet<>(s, mutex);

}

/***@serialinclude*/static classSynchronizedSet

extendsSynchronizedCollection

implementsSet {

private static final longserialVersionUID= 487447009682186044L;

SynchronizedSet(Set s) {

super(s);

}

SynchronizedSet(Set s, Object mutex) {

super(s, mutex);

}

public booleanequals(Object o) {

if(this== o)

return true;

synchronized(mutex) {returnc.equals(o);}

}

public inthashCode() {

synchronized(mutex) {returnc.hashCode();}

}

}

我们可以通过代码看到他是实现了一个静态方法,在静态方法中去创建这个静态类,而这个静态类重写了集合中有资源竞争关系的方法(加了同步处理)

参考:Java面向对象编程--孙卫琴

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值