synchronized 与 Lock区别

在上一篇文章中,我们谈到了采用synchronized来实现多线程同步,在Java中还一种实现多线程同步的方法,那就是Lock。下面主要谈谈这两种多线程同步的区别。
1、synchronized是在JVM层面实现的,系统可以监控锁的释放与否。
2、ReentrantLock使用代码实现的,系统无法自动释放锁,需要在代码中finally子句中显式释放锁lock.unlock()。
3、相对于synchronized,ReentrantLock还多了 锁投票,定时锁等候和中断锁等候。
例:线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,
如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断
如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情。
4、synchronized是由系统监控,对于业务不是很熟悉的开发者来说,用起来更省心,但是在并发量比较高的情况下,其性能下降很严重,此时ReentrantLock是个不错的方案。

用Lock实现同步例子:

public class Consumer implements Runnable {

     private Lock lock;
     public Consumer(Lock lock) {
            this. lock = lock;
     }
     @Override
     public void run() {
            // TODO Auto-generated method stub
            int count = 10;
            while( count > 0 ) {
                 try {
                      lock.lock();
                     count --;
                     System. out.print( "B");
                } finally {
                      lock.unlock(); //主动释放锁
                      try {
                           Thread. sleep(91L);
                     } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                           e.printStackTrace();
                     }
                }
           }

     }

}

public class Producer implements Runnable{

     private Lock lock;
     public Producer(Lock lock) {
            this. lock = lock;
     }
     @Override
     public void run() {
            // TODO Auto-generated method stub
            int count = 10;
            while (count > 0) {
                 try {
                      lock.lock();
                     count --;
                     System. out.print( "A");
                } finally {
                      lock.unlock();
                      try {
                           Thread. sleep(90L);
                     } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                           e.printStackTrace();
                     }
                }
           }
     }
}

调用代码:

public class Test {

     public static void main(String[] args) {
           Lock lock = new ReentrantLock();

           Consumer consumer = new Consumer(lock);
           Producer producer = new Producer(lock);

            new Thread(consumer).start();
            new Thread( producer).start();

     }
}

忠告:多线程同步的时候,优先考虑synchronized,如果有特殊需要,再进一步优化。ReentrantLock和Atomic如果用的不好,不仅不能提高性能,还可能带来灾难。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值