JDK源码研究之concurrent

ava.util.concurrent包中包含了Java并发编程的解决框架

1、synchronized:在JAVA中每个对象其实都有一个隐藏的锁对象,当给方法加上szhcnronized的时候相当于该对象加上同步块。比如
   public class Adder{
  public int i;
  public synchronized void add(){i++;};
   }
   其实它与
   public class Adder{
  public int i;
  Object lock = new Object();
  public void add(){
   synchronized(lock){
    i++;
   };
  };
   }是一样的道理,只不过前者用到的锁是隐藏的,如果外部也想获得该锁便无能为力了。如果还只是这样的案例那么自己定义一个Object,再用同步块的方法也能够解决问题。实际多线程编程并不如此简单,请看2

2、ReentranLock,可重入的锁,标准使用方式为
   lock.lock();
   try{...;}catch(Exception e){}finally{lock.unlock();},这个东西刚出来的时候网上就有好多人浮燥地认为ReentranLock比synchronized要高效,
   我敢保证,很多搞J2EE的都是人云亦云之辈,没有做过深入的调查的。就拿上面多线程加法运算来说吧,100万次加法的时候synchronized关键字与synchronzed同步块所需的时候非常接近。
   而ReentranLock则需要耗费较多时间,我猜应该是try{}catch块影响了效率。所以说在简单的同步代码中完全没必要用到ReentranLock,除非你确实没办法只用synchronzed解决问题,或者需要synchronzed + Object的wait()/notify()
   的时候才需要考虑引入ReentranLock。哎,现在的程序员为什么都越来越浮燥了呢,搞不懂,一有新的东西出来就一窝蜂似地跑过去追逐,跟追星族有什么两样?静下心来学基础才是最重要的。

3 volatile,这个东西呢其实也就是声明你的变量在做运算的时候只有主存中的那一份。只有一份东西了,多个线程对它做操作肯定是安全的了吧?错!虽然东西只有一份,但它只对原子操作才安全。例如

  valatile i;
  public void add(){
   int i++;
  }
  上面是典型的错误代码,因为i++是一个compareAndSwap操作,先比较再赋值,有可能这个线程在比较完的时候另外一个线程刚好做了赋值操作,而当前线程又做赋值操作的时候用的还是老的值,结果造成丢1。

  而对于形如 public void setI(int i){this.i = i;} 这样的操作是安全的。

4、atomic包,提供了原子更新字段的若干类,AtomicBoolean、AtomicInteger、AtomicLong分别是原子更新boolean integer和long的三个类,而AtomicIntegerArray和AtomicLongArray分别是用来原子更新integer[]和long[]的。AtomicIntegerFieldUpdate和AtomicLongFieldUpdate分别是用反射的方式来更新
   一个对象里面的volatile的int和long字段的。AtomicReference这个类比较经常关键,是用来原子更新引用的。其实原子更新是基于Compare And Swap(CAS)来完成的。每个类的内部其实也是通过调用sun.misc.Unsafe的comapreAndSet来实现的。

5、locks包。还看不太懂AbstractQueuedSynchronizer和具体机制,只知道是将线程维护在一个双向队列里,然后根据外部的acquire或release来锁定或释放。Lock ReadWriteLock ReteenLock 及Condition是Dong Lea提供给我们使用的现成的东东。
   Condition属于Lock,这样就可以通过condition的await或signal来阻塞线程,这事要换做以前得用synchronized + Object的基础wait/notify才能搞定。


6、ArrayBlockingQueue,一个指定大小的可阻塞队列。BlockingDeque是双向的可阻塞队列。

7、ConcurrentHashMap。这东西说白了就是把分段存储,基于段的锁定,在写操作的时候不同段之间便无需同步。在读操作的时候不上锁读,当元素为空时(刚好有读线程在进行设置操作)再上锁读。效率相当高。

8、至于CopyOnWrite的东东只建议在极少写操作的时候才使用它,特别是在元素多的时候copy是相当耗时的。

....

你可能感兴趣的:(jdk,多线程,编程,框架,sun)