android 随笔——队列、同步、锁

通常情况下,应用程序会在一个线程中生产数据,在另一个线程中使用它们。常见的例子是在一个线程中获取网络上的数据,在另一个线程中把这些数据展现给用户。这种模式成为生产者/消费者模式,在面向对象的编程中,开发者用算法来实现要花上几个小时。现在就来介绍一些简化生产者消费者模式实现的现成类。

1、更智能的队列

虽然已有现成的类并能用更少的代码实现该功能,但许多Java开发者仍然选择使用LinkedList以及同步块实现队列功能。下面使用标准的LinkedList实现线程安全队列的代码。

public class ThreadSafeQueue{

  private LinkedList<String> mList=new LinkedList<String>();

  private final Object mLock=new Object();

public void offer(String value){

          synchronized(mLock){

                 mList.offer(value);

                  mLock.notifyAll();

                     }

           }

public synchronized String poll(){

    synchronized(mLock){

     while(mList.isEmpty){

         try{

                     mLock.wait();

           }catch(InterruptedException e){

                         //简介起见忽略异常处理

                        }

                  }

               return mList.poll();

                     }

           }

}

虽然这段代码是正确的,并有可能得满分,但实现和测试这样一段代码只是浪费时间。实际上,所有前面的代码都可以用下面的一行代码代替。

LinkedBlockingQueue<String> blockingQueue=new LinkedBlockingQueue<String>();

上面的代码能像前面的例子一样提供相同类型的阻塞队列,甚至能提供额外的线程安全操作。


2、更智能的锁

Java 提供的synchronized关键字允许开发者创建线程安全的方法和代码块。synchronized关键字容易使用,也容易滥用,对性能造成负面影响。当需要区分读数据和写数据时,synchronized关键字并不是最有效的。幸好,java.util.concurrent.locks包中的工具类对这种情况提供了很好的支持。

public  class ReadWriteLockDemo{

      private final ReentrantReadWriteLock mLock;

     private String mName;

      private int mAge;

     private String mAddress;

    public ReadWriteLockDemo(){

         mLock=new ReentrantReadWriteLock();

}

public void setPersonData(String name,int age,String address){

           ReentrantReadWriteLock,WriteLock writeLock=mLock.writeLock();

                    try{

                                writeLock.lock();

                                mName=name;

                                mAge=age;

                                mAddress=address;

                               }finally{

                                     writeLock.unlock();

                                    }

                         }

public String getName(){

     ReentrantReadWriteLock.ReadLock readLock=mLock.readLock();

            try{

                 readLock.lock();

                 return mName;

                         }finally{

                               readLock.unlock();

                    }

   }

}

上面的代码展示了在什么地方使用ReentrantReadWriteLock,它允许多个并发线程对数据进行只读访问,并确保同一时间只有一个线程写入相同的数据。

在代码 中使用synchronized关键字仍然是处理所问题的有效方法,但无论何种情况下,都要考虑ReentrantReadWriteLock是否是更有效的解决方案。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值