java中synchronized关键字与ReentrantLock对比

版权声明:本文为博主学习笔记, 注明来源情况下随意转载 https://blog.csdn.net/lengxiao1993/article/details/81455618

参考文章

synchronized 关键字的可重入性

  • 在 java 中被 synchronized 关键字所修饰的代码块是支持重入的。 也就是说, 当一个java线程进入了某个对象的 synchronized 代码块后, 还能够再次进入该对象其他的synchronized 代码块。
  • 需要重复进入同一个对象的 synchronized 方法的最常见情形是被 synchronized 修饰的递归方法
  • 通过下面的例子可以很清晰的展示出synchronized 的可重入性。
public class Reentrance {
    public synchronized void outter(){
        System.out.println("enter outter ");
        inner();
    }
    public synchronized void inner(){
        System.out.println("enter inner");
    }

   public static void main(String[] args) {
        new Reentrance().outter();
    }
}


output:
outter enter
inner enter

synchronized 关键字与ReentrantLock 区别

  • 既然synchronized 关键字是支持重入的, 那么为什么还要引入 ReentrantLockReentrantLocksynchronized 关键字的区别在哪
    • 区别1: ReentrantLock 支持对锁的公平性(fairness)控制, synchronized 关键字不支持公平性的控制。
      • 构造函数 ReentrantLock(boolean fair) 可以通过参数 boolean 值指定锁是需要将所提供给等待时间最长的线程还是随机竞争获得所。
    • 区别2: ReentrantLock 提供了一个很synchronized 关键字不具备的方法 tryLock() 。 该方法仅仅当锁未被其他线程占用的时, 才会获取锁, 这样可以减少同一时刻阻塞在同一个锁上的线程数量。
    • 区别3: ReentrantLock 在锁定期间, 是可以被其他线程打断的 (interrupt), synchronized 关键词的线锁修饰的方法是可以被长期或一直阻塞。
    • 区别3: 正在等待 ReentrantLock的线程是可以被中断的,而 synchronized 关键词则不具备这种能力。
    • 区别4: ReentrantLock 还提供了获取所有等待锁线程的List 的方法
    • 区别5: ReentrantLock 提供了条件变量Condition 的构造方法newCondition()
  • 下面这个例子简单展示了如何使用ReentrantLock进行代码的同步控制
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Java program to show, how to use ReentrantLock in Java.
 * Reentrant lock is an alternative way of locking
 * apart from implicit locking provided by synchronized keyword in Java.
 *
 * @author  Javin Paul
 */
public class ReentrantLockHowto {

    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

     //Locking using Lock and ReentrantLock
     public int getCount() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " gets Count: " + count);
            return count++;
        } finally {
            lock.unlock();
        }
     }

     //Implicit locking using synchronized keyword
     public synchronized int getCountTwo() {
            return count++;
     }



    public static void main(String args[]) {
        final ThreadTest counter = new ThreadTest();
        Thread t1 = new Thread() {

            @Override
            public void run() {
                while (counter.getCount() <= 6) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();                    }
                }
            }
        };

        Thread t2 = new Thread() {

            @Override
            public void run() {
                while (counter.getCount() <= 6) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        };

        t1.start();
        t2.start();

    }
}

Output:
Thread-0 gets Count: 0
Thread-1 gets Count: 1
Thread-1 gets Count: 2
Thread-0 gets Count: 3
Thread-1 gets Count: 4
Thread-0 gets Count: 5
Thread-0 gets Count: 6
Thread-1 gets Count: 7

猜你喜欢

转载自blog.csdn.net/lengxiao1993/article/details/81455618