并发入门

引例

如下:
    private int a;
    private void test() {
        ExecutorService pool = Executors.newFixedThreadPool(10);
        for(int x = 0;x<10;x++){
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    log();
                }
            });
        }
    }
    private void log(){
        a++;
        Thread.yield();
        a++;
        Log.e("TAST","a = "+a+",currentThread ="+ Thread.currentThread());
    }

        在上面代码中,正常逻辑下, 每一次输出的应该都是偶数。但涉及多线程时,有些时候会输出奇数。

yield()

        当前线程释放CPU资源,由CPU随机选择一个线程执行——有可能是调用yield()方法的线程。上述代码中调用yield()的主要作用就是调用可能存在的并发问题暴露的机率。

原因

        多个线程访问同一共享性资源,而共享性资源又非原子性操作(如赋值,返回这样的操作是无法打断的,称它们具有原子性,而a++方法是可能被打断的,所以非原子性)。

        上述代码中,多个线程调用了同一个log()方法,这个log()方法就是共享性资源。

synchronized

        修饰方法时:为方法加锁,这样该方法同时只能被一个线程进行操作。同一个对象中,所以sync方法共用同一个锁,一个线程可以多次获取一个对象的锁,因此多个线程也只有一次调用该对象中一个方法。例如t1,t2为两个线程,前者访问sync方法f1,后者访问sync方法f2。如果t1先执行且未执行完毕之前,t2是无法访问到f2的。因为f1与f2的锁一致,t1访问时该锁被锁上了。但t1可以再访问f2。

        可以使用sync对上述代码中的log进行修饰加锁,就会避免并发问题。

Lock

        lock必须被显式的创建、加锁与释放。如,

    private void log(){
        lock.lock();//lock是ReentrantLock
        try{
            a++;
            Thread.yield();
            a++;
            Log.e("TAST","a = "+a+",currentThread ="+ Thread.currentThread());
        }finally {
            lock.unlock();
        }
    }

        上述代码中,在finally()中调用lock#unlock()。这就保证了必须会调用到unlock()。

        有一点要注意:如果该方法有返回值的话, 必须放在try中写,用于确保return语句不会过早发生,从而将结果暴露给别的线程

常用方法

        tryLock():尝试获取锁,如果能获取成功就立即返回true,如果不能获取成功就立即返回false。

        tryLock(long,TimeUnit):在指定的时间内如果能获取锁,就返回true,否则返回false。在此过程中,会被intercept掉。

比较

        与sync类似,都是用来进行加锁处理同步问题的。但使用sync关键字,代码更少,并且出错的可能性也会降低。因此通常只在解决特殊问题的时候才使用lock。

        使用lock,使程序拥有更细粒度的控制力。还允许尝试获取锁——结果不一定能获取到。并且在锁内部如果出现异常,还可以在finally中进行清理操作。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值