关于java中同步异步的处理

    说起多线程同步是必须要考虑的问题,以前也对同步有所了解,但都处于简单的使用。
     这是我们第一想到的是关键字 synchronized,这是我们最通用也是平时程序中处理同步最常见的办法。其使用方法就不用再说了。看看那个声明对象就知道要用该对象的锁进行同步。
     或许你还会想起关键字volatile,用来使一个对象读值和写值的同步,但其也有一些不能使用的场景。
     此外,我们还会使用object的wait, notice等方法 利用对象锁达到同步的效果,不过这离不开synchronized,因为先要获得锁才能wait。
     上面三种是比较常见 和 直接的 同步方法。其实java本身提供给了我们一些实现同步的工具类,其位于 包 java.util.concurrent 下,下面我对这个包下面几个子包的内容作以简单介绍:
  •       java.util.concurrent:这个包中包含的类为一些高级的同步工具,包含了一些线程的顺序执行,条件执行,线程池等工具,具体使用看看demo

  •       java.util.concurrent.atomic:这个包中主要是用来来实现一些后来出来的新的CPU支持了compareAndUpdate指令,如果当前CPU不支持该指令会使用锁机制来实现。其下面的AtomicLong和AtomicInteger类在实现计数时非常简单,我们不需要去考虑多线程同步问题。实例代码如下:
    public  class  IdGenerator
    {
             private  final  static  AtomicLong  creator  =  new  AtomicLong(0);

             public  static  long  newId()
           {
                    return  creator  .getAndIncrement();
           }
    }
    下面一段是用来更新volatile 字段值的:
    public class ReferenceFieldUpdate
    {
            private volatile Object obj;

            private final AtomicReferenceFieldUpdater<ReferenceFieldUpdate, Object> aUpdate = AtomicReferenceFieldUpdater
                  . newUpdater(
                         ReferenceFieldUpdate. class, Object.class , "obj" );

            public void compareAndSet(Object expect, Object update)
           {
                   aUpdate.compareAndSet(
                          this, expect, update);
           }
    }
  •       java.util.concurrent.locks:这个包中的一些类,可以自己写一些手动获得对象锁,释放对象锁,使用起来更加灵活。具体例子看看doc中的demo.

    在java7 中引入了一下同步工具:
ForkJoin 框架,位于java.util.concurrent包下,用来实现将比较大的任务进行分割求解,在综合的多线程池。比如在数据结构中我们的二分查找法用这个实现起来就能够用多线程来提高查找效率,但也不必我们去考虑线程的同步问题。下面是一段实例代码:
public  class  MaxValueCaculator
{
         private  final  ForkJoinPool  pool  =  new  ForkJoinPool(15);

         private  final  int  SPLIT_NUM  = 100;

         private  class  MaxCaculateTask  extends  RecursiveTask<Long>
       {
                private  long  datas  [];

                private  int  start  ;

                private  int  end  ;

                public  MaxCaculateTask( long [] datas,  int  start,  int  end)
              {
                       super ();
                       this . datas  = datas;
                       this . start  = start;
                       this . end  = end;
              }

                @Override
                protected  Long compute()
              {
                       long  max = Long. MIN_VALUE ;
                       if  ( end  -  start  >  SPLIT_NUM  )
                     {
                             int  mid = ( end  +  start  ) / 2;
                           MaxCaculateTask left =  new  MaxCaculateTask( datas  ,  start , mid);
                           MaxCaculateTask rigth =  new  MaxCaculateTask( datas  , mid,  end );
                           left.fork();
                           rigth.fork();
                           max = Math. max(
                                  max, left.join());
                           max = Math. max(
                                  max, rigth.join());
                     }
                       else
                     {
                             for  ( int  i =  start  ; i <  end  && i <  datas .  length ; i++)
                           {
                                  max = Math. max(
                                         max,  datas [i]);
                           }
                     }
                       return  max;
              }

       }
         public  Long caculte( long [] datas){
              MaxCaculateTask task =  new  MaxCaculateTask(datas, 0, datas. length  );
                return  pool  .invoke(task);
       }
         public  static  void  main(String[] a){
              MaxValueCaculator c=  new  MaxValueCaculator();
                long  datas[]= new  long [1];
                long  cur=System.currentTimeMillis();
                for ( int  i=-111111, j=0;i<11111;i++,j++){
                     datas[j]=i;
                       long  temp[]= new  long [datas. length +1];
                     System. arraycopy(datas, 0, temp, 0, datas. length );
                     datas=temp;
              }
              System.  out .println(System.currentTimeMillis()-cur+  "Ms" );
              cur=System. currentTimeMillis();
              System.  out .println(c.caculte(datas));
              System.  out .println(System.currentTimeMillis()-cur+  "Ms" );
       }
}
  • Phaser:也是java7引入的一个解决线程互斥问题的类,该类使用更见灵活,不仅能够实现在某种条件下执行线程的功能还能实现执行达到某个条件停止执行线程的功能。其例子看看http://www.open-open.com/lib/view/open1325208929936.html, 感觉写的还不错。

    此外我们对于一些线程级的变量可以使用ThreadLocal类实现。对于每个线程来说使用该类获得的对象是对于线程独立的。
    对于多线程产生随机数时,java7中可以使用ThreadLocalRandom 来提高生成效率。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值