Jav并发

Java 阻塞队列

 

      ArrayBlockingQueue 

      LinkedBlockingQueue 

      SynchronousQueue 

用put() 和 take() 是阻塞
不要用poll()和offer() ,要用也要用带时间参数的 

锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如 ReadWriteLock 的读取锁。

synchronized 每个对象相关的隐式监视器锁的访问,强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。
Lock

Lock 实现提供了使用 synchronized 方法和语句所没有的其他功能,包括提供了一个非块结构的获取锁尝试 (tryLock())、一个获取可中断锁的尝试 (lockInterruptibly()) 和一个获取超时失效锁的尝试 (tryLock(long, TimeUnit))。

Lock 类还可以提供与隐式监视器锁完全不同的行为和语义,如保证排序、非重入用法或死锁检测。如果某个实现提供了这样特殊的语义,则该实现必须对这些语义加以记录。 

 

ReentrantLock
一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

Condition

ConditionObject 监视器方法( waitnotifynotifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中, Lock 替代了 synchronized 方法和语句的使用, Condition 替代了 Object 监视器方法的使用。

使用Atomic 包
使用阻塞队列

lock-free 算法
1 循环 ( for (;;))
2 CAS  compareandset   Compareand-Swap
原子操作指一个cpu时钟周期内就可以完成的操作,不会被其他线程干扰。
          {if( *pVal == oldVal )  { *pVal = newVal; return true;} return false;}
3 回退

1 使用CAS结构的数据结构,避免使用锁,如AtomicXXX、ConcurrentMap、CopyOnWriteList、ConcurrentLinkedQueue
2 注意锁的顺序
3, 通过dump kill -3 等查看死锁信息
4 注意外部锁,比如数据库的锁 文件的锁
Map 用ConcurentHashMap 取代
避免直接使用锁,锁由数据结构管理

ScheduledExecutorService,不建议你再使用java.util.Timer

Amdahl 定律 
    – Gene Amdahl 发现在计算机体系架构设计过程中,即使你有10个老婆,也不能 
      某个部件的优化对整个架构的优化和改善是有                    一个月把孩子生下来。 
      上限的。这个发现后来成为知名的Amdahl 定律。 

•Gustafson 定律 
    – Gustafson假设随着处理器个数的增加,并行与               当你有10个老婆,就会要生 
       串行的计算总量也是可以增加的。Gustafson定 
      律认为加速系数几乎跟处理器个数成正比,如                    更多的孩子。 
      果现实情况符合Gustafson定律的假设前提的话, 
      那么软件的性能将可以随着处理个数的增加而 
      增加。 

•Sun-Ni 定律 
    – 充分利用存储空间等计算资源,尽量增大问题                    你要设法让每个老婆都在干 
      规模以产生更好/更精确的解。                          活,别让她们闲着。 



CountDownLatch
当你启动很多线程,你需要这些线程等到通知后真正开始,用countdownlatch
 当你启动了一个线程,你需要等它执行结束, 此时,CountDownLatch也许是一个很好的选择。 

CAS注

CAS在我的理解就是下面这段代码


{if( *pVal == oldVal )  { *pVal = newVal; return true;} return false;}

当然,CAS把这段代码做成了一个原子操作。

很多人看到这里,并不是十分理解,这个原子操作怎么去实现LOCK FREE。

一般CAS会封装成下面的形式

    bool cas32( int * pVal, int oldVal, int newVal );

pVal 表示要比较和替换数值的地址,oldVal表示期望的值,newVal表示希望替换成的值。在多线程中使用时,一般是下面这样。

    volitale int myValue;
    ......

    while( !cas32( &myValue, myValue, myValue+1 ) ) {
        ....
    }

这是什么意思呢?
我们知道,在多线程里面,如果多个线程同时在写一个变量,并且不进行同步的时候,这个变量的值就会不准确。比如两个线程同时在对一个变量进行+1操作的时候,他们分别需要进行三个操作,读入变量值(到寄存器),值+1,写入变量值(到变量内存地址)。这三个操作是无法保证原子性的,也就无法保证变量在读入,+1后,原变量没有被别的线程修改。
cas在这里做的实际上就是在变量没有被其他线程修改,或者被修改但是又恢复到我们期望读入的值的时候,修改变量的值。这句话很拗口,其实看CAS的参数就很容易理解,pVal传递进去的是变量的地址,cas通过这个来读取变量真实的值,oldVal传递的是变量在函数调用时的值,用来跟真实值进行比较,而newVal传递进去的是期望变量赋予的新的值。根据上面的cas的代码含义我们知道,当变量真实值不等于调用时的值的时候,是不会赋予变量新的值的。所以我们使用了一个WHILE来等待这个赋值成立。同时我们给与myValue一个volitale修饰,用意是让while中调用cas函数时,读取myValue的当前值,而不是寄存器中保存的值,以免变量值的“过期”,从而让这个cas可以在没有其他线程来修改myValue的时候执行成功,从而实现lock free的修改myValu
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值