Java 多线程

1:静态条件

基于一种可能失效的观察结果做出判断或执行某个计算

2:原子性

原子是世界上的最小单位,具有不可分割性。比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++; 这个操作实际是a = a + 1;是可分割的,所以他不是一个原子操作。非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。java的concurrent包下提供了一些原子类,我们可以通过阅读API来了解这些原子类的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。

3:可见性

可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被他修饰内容具有可见性,但不能保证它具有原子性。比如 volatile int a = 0;之后有一个操作 a++;这个变量a具有可见性,但是a++ 依然是一个非原子操作,也就这这个操作同样存在线程安全问题。

原子性是说一个操作是否可分割。可见性是说操作结果其他线程是否可见。这么看来他们其实没有什么关系。

4:volatile变量解释

   用来确保将变量的更新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作仪器重新排序,volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方。因此在读取volatile类型的变量时总会返回最新写入的新值。访问volatile变量不会执行加锁操作,因此就不会有线程阻塞,因此volatile变量是一种比sychronized更轻量级的同步机制。

  volatile变量通常用做,某个操作完成,发生中断或者状态的标志,但是不足以确保递增操作的原子性,加锁能确保可见性与原子性。

5:发布与逸出

发布:使对象能够在当前作用域之外的代码中使用

逸出:当某个不应该发布的对象被发布时

6:同步容器类

同步容器类包括Vector 和 Hashtable 他们实现线程安全的方式是:将他们的状态封装起来,并对每个公有方法都进行同步,使得每次只有一个线程能访问容器的状态。

同步容器类都是线程安全的,但有些情况下可能需要额外的客户端加锁来保护复合操作。例如容器迭代过程中并发修改,需要获得这个容器的自身的锁,但是可能会出现死锁或饥饿。如果不希望在迭代期间对容器加锁,那么一种替代方法就是克隆,在副本上进行迭代。当发现容器在迭代过程中被修改时,就会抛出一个ConcurrentModificationException.还考虑隐藏迭代器:toString,hashMap,equals。

ConcurrentHashMap 也是一个基于散列的Map,并不是将每个方法都在同一个锁上同步并使得每次只能有一个线程访问容器,而是使用一种粒度更细的加锁机制来实现更大程度的共享,这种机制称为分段锁。他提供的迭代器不会抛出ConcurrentModificationException,因此不需要在迭代过程中加锁。




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值