重入锁与同步关键字sychronized

重入锁采用ReentrantLock 实现,和同步关键字sychronized都可以用来在多线程环境下保护临界区资源,确保安全性。重入锁相比sychronized有着显示的操作过程,需要手动控制何时加锁和解锁(如不解锁则会造成死锁),之所以称为重入锁,是因为锁是可以反复进入的,即同一个线程可以连续多次获得锁而不会造成死锁,相应的解锁也需要多次,否则会造成其它线程因为获取不到锁而无法访问临界区资源。

重入锁可以替换sychronized,instance是类的实例,请自行添加ReenterLock instance = new ReenterLock();例如:

public class ReenterLock implements Runnable{

    private static ReentrantLock lock = new ReentrantLock();
    private static int i = 0;

    @Override
    public void run() {
        for (int j = 0; j < 100000; j++) {
	    //加锁保证对变量i的安全访问	
            lock.lock();
            try {
                i++;
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException{
	//注意两个线程要指向的是同一实例(关注的是同一个对象锁)
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }
}
用同步关键字也是保证对变量 i 访问的安全性的,例如:

public class ReenterLock implements Runnable{

    private static ReenterLock instance = new ReenterLock();
    private static int i = 0;

    public static synchronized void increase() {
        i++;
    }

    //两种同步方式都可行,任选一种	
    @Override
    public void run() {
        for (int j = 0; j < 100000; j++) {
            synchronized (instance) {
                i++;
            }
        }
    }

    /*@Override
    public void run() {
        for (int j = 0; j < 100000; j++) {
            increase();
        }
    }*/

    public static void main(String[] args) throws InterruptedException{
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }
}
使用重入锁和同步关键字输出结果均是一致的。

关于重入锁的高级应用,如中断响应、限时等待锁、condition条件,有兴趣的可以自行了解。推荐书籍:实战java高并发程序设计


你可能感兴趣的:(重入锁与同步关键字sychronized)