Java并发编程原理(四)

lock锁

public class LockDemo {
    private Lock lock = new ReentrantLock();
    private int count = 0;

    public int inc() {
        lock.lock();
        try {
            int newCount = count++;
        } finally {
            //保证锁最终被释放
            lock.unlock();
        }
        return newCount;
    }
}

ReentrantLock()是实现lock接口的子类,调用lock的lock()方法对非原子性操作进行锁定,使用try finally 保证在出现异常时,锁能够最终被释放。

实现自己可重入的MyLock

  • 什么是可重入锁
private MyLock mylock =new MyLock();
public void getA(){
    mylock.lock();
    System.out.println("调用a方法");
   getB();
    mylock.unlock();
}

public  void getB(){
    mylock.lock();
    System.out.println("调用b方法");
    mylock.unlock();
}

getA()和getB()使用的是同一个mylock锁,所以getA()中调用getB()的操作就被视为是锁的重入。

如果一个线程已经拥有了一个管程对象上的锁,那么它就有权访问被这个管程对象同步的所有代码块。这就是可重入。线程可以进入任何一个它已经拥有的锁所同步着的代码块。

public class MyLock {
    private boolean flag=false;

    private int count = 0;//记录加锁次数

    private Thread thread = null;//记录当前线程

    public synchronized  void lock() {
        try {
           Thread callingThread = Thread.currentThread();
            //自旋
            while (flag && thread != callingThread )
            wait();
            flag=true;
            count++;
            thread = callingThread;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }




    public synchronized void unlock() {
	//是当前线程
        if (Thread.currentThread() == this .thread){
        //将计数器置为0
            count--;
            if (count == 0){
                flag=false;
                thread=null;
                notify();
            }
        }
        flag=false;
        notify();
    }

}

重入锁的关键是保证同一个线程持有锁,如果flag=true并且不是当前线程(flag && thread != callingThread ),让其它线程自选等待。

接下来讨论公平锁和读写锁

发布了47 篇原创文章 · 获赞 18 · 访问量 5727

猜你喜欢

转载自blog.csdn.net/yuruizai110/article/details/86710195
今日推荐