1.原始构成

  • synchronized是关键字属于JVM层面,
    monitorentry(底层是通过monitor对象来完成,其wait/notify等方法也是依赖于monitor对象只有在同步块或方法中才能调用wait/notify等方法)
    monitorexit
  • Lock是具体类(java.util.concurrent.locks.lock)是api层面的锁

2.使用方法

  • synchronized不需要用户去手动释放锁,当synchronized代码执行完后系统会自动让线程释放对锁的占用
  • ReentrantLock则需要用户去手动释放锁若没有释放锁,就有可能导致出现死锁的现象。需要lock()和unlock()方法配合try/finally语句块来完成。

3.等待是否可中断

  • synchronized不可中断,除非抛出异常或者正常运行完成
  • ReentrantLock可中断
    • 1.设置超时方法tryLock(long timeout,TimeUnit unit)
    • 2.lockInterruptibly()放代码块中,调用interrupt()方法中断

4.加锁是否公平

  • synchronized非公平锁
  • ReentrantLock两者都可以,默认非公平锁,构造方法可以传入boolean值,true为公平锁,false为非公平锁

5.锁绑定多个条件Condition

  • synchronized没有
  • ReentrantLock用来实现分组唤醒需要唤醒的线程们,可以精确唤醒,而不是像synchronized要么随机唤醒一个线程,要么唤醒全部线程

锁绑定多个条件Condition:
题目:多线程之间按顺序调用,实现A->B->C 三个线程启动,要求如下:
A打印5次,B打印10次,C打印15次,紧接着
A打印5次,B打印10次,C打印15次
。。。
来10轮
示例代码:

class ShareResource {
    private int number = 1;

    private Lock lock = new ReentrantLock();

    private Condition c1 = lock.newCondition();

    private Condition c2 = lock.newCondition();

    private Condition c3 = lock.newCondition();

    public void print5(int n) {
        try {
            lock.lock();
            while (number != 1) {
                //等待
                c1.await();
            }
            //打印
            for (int i = 1; i <= 5; i++) {
                System.out.println(n + "轮" + Thread.currentThread().getName() + "\t" + i);
            }

            //设置标志位
            number = 2;

            //唤醒下一个线程
            c2.signal();


        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void print10(int n) {
        try {
            lock.lock();
            while (number != 2) {
                //等待
                c2.await();
            }
            //打印
            for (int i = 1; i <= 10; i++) {
                System.out.println(n + "轮" + Thread.currentThread().getName() + "\t" + i);
            }

            //设置标志位
            number = 3;

            //唤醒下一个线程
            c3.signal();


        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void print15(int n) {
        try {
            lock.lock();
            while (number != 3) {
                //等待
                c3.await();
            }
            //打印
            for (int i = 1; i <= 15; i++) {
                System.out.println(n + "轮" + Thread.currentThread().getName() + "\t" + i);
            }

            //设置标志位
            number = 1;

            //唤醒下一个线程
            c1.signal();


        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

public class SyncAndReentrantLockDemo {

    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();

        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                shareResource.print5(i);
            }
        }, "A").start();

        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                shareResource.print10(i);
            }
        }, "B").start();

        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                shareResource.print15(i);
            }
        }, "C").start();
    }
}

运行结果:

1轮A	1
1轮A	2
1轮A	3
1轮A	4
1轮A	5
1轮B	1
1轮B	2
1轮B	3
1轮B	4
1轮B	5
1轮B	6
1轮B	7
1轮B	8
1轮B	9
1轮B	10
1轮C	1
1轮C	2
1轮C	3
1轮C	4
1轮C	5
1轮C	6
1轮C	7
1轮C	8
1轮C	9
1轮C	10
1轮C	11
1轮C	12
1轮C	13
1轮C	14
1轮C	15
2轮A	1
2轮A	2
2轮A	3
2轮A	4
2轮A	5
2轮B	1
2轮B	2
2轮B	3
2轮B	4
2轮B	5
2轮B	6
2轮B	7
2轮B	8
2轮B	9
2轮B	10
2轮C	1
2轮C	2
2轮C	3
2轮C	4
2轮C	5
2轮C	6
2轮C	7
2轮C	8
2轮C	9
2轮C	10
2轮C	11
2轮C	12
2轮C	13
2轮C	14
2轮C	15
3轮A	1
3轮A	2
3轮A	3
3轮A	4
3轮A	5
3轮B	1
3轮B	2
3轮B	3
3轮B	4
3轮B	5
3轮B	6
3轮B	7
3轮B	8
3轮B	9
3轮B	10
3轮C	1
3轮C	2
3轮C	3
3轮C	4
3轮C	5
3轮C	6
3轮C	7
3轮C	8
3轮C	9
3轮C	10
3轮C	11
3轮C	12
3轮C	13
3轮C	14
3轮C	15
4轮A	1
4轮A	2
4轮A	3
4轮A	4
4轮A	5
4轮B	1
4轮B	2
4轮B	3
4轮B	4
4轮B	5
4轮B	6
4轮B	7
4轮B	8
4轮B	9
4轮B	10
4轮C	1
4轮C	2
4轮C	3
4轮C	4
4轮C	5
4轮C	6
4轮C	7
4轮C	8
4轮C	9
4轮C	10
4轮C	11
4轮C	12
4轮C	13
4轮C	14
4轮C	15
5轮A	1
5轮A	2
5轮A	3
5轮A	4
5轮A	5
5轮B	1
5轮B	2
5轮B	3
5轮B	4
5轮B	5
5轮B	6
5轮B	7
5轮B	8
5轮B	9
5轮B	10
5轮C	1
5轮C	2
5轮C	3
5轮C	4
5轮C	5
5轮C	6
5轮C	7
5轮C	8
5轮C	9
5轮C	10
5轮C	11
5轮C	12
5轮C	13
5轮C	14
5轮C	15
6轮A	1
6轮A	2
6轮A	3
6轮A	4
6轮A	5
6轮B	1
6轮B	2
6轮B	3
6轮B	4
6轮B	5
6轮B	6
6轮B	7
6轮B	8
6轮B	9
6轮B	10
6轮C	1
6轮C	2
6轮C	3
6轮C	4
6轮C	5
6轮C	6
6轮C	7
6轮C	8
6轮C	9
6轮C	10
6轮C	11
6轮C	12
6轮C	13
6轮C	14
6轮C	15
7轮A	1
7轮A	2
7轮A	3
7轮A	4
7轮A	5
7轮B	1
7轮B	2
7轮B	3
7轮B	4
7轮B	5
7轮B	6
7轮B	7
7轮B	8
7轮B	9
7轮B	10
7轮C	1
7轮C	2
7轮C	3
7轮C	4
7轮C	5
7轮C	6
7轮C	7
7轮C	8
7轮C	9
7轮C	10
7轮C	11
7轮C	12
7轮C	13
7轮C	14
7轮C	15
8轮A	1
8轮A	2
8轮A	3
8轮A	4
8轮A	5
8轮B	1
8轮B	2
8轮B	3
8轮B	4
8轮B	5
8轮B	6
8轮B	7
8轮B	8
8轮B	9
8轮B	10
8轮C	1
8轮C	2
8轮C	3
8轮C	4
8轮C	5
8轮C	6
8轮C	7
8轮C	8
8轮C	9
8轮C	10
8轮C	11
8轮C	12
8轮C	13
8轮C	14
8轮C	15
9轮A	1
9轮A	2
9轮A	3
9轮A	4
9轮A	5
9轮B	1
9轮B	2
9轮B	3
9轮B	4
9轮B	5
9轮B	6
9轮B	7
9轮B	8
9轮B	9
9轮B	10
9轮C	1
9轮C	2
9轮C	3
9轮C	4
9轮C	5
9轮C	6
9轮C	7
9轮C	8
9轮C	9
9轮C	10
9轮C	11
9轮C	12
9轮C	13
9轮C	14
9轮C	15
10轮A	1
10轮A	2
10轮A	3
10轮A	4
10轮A	5
10轮B	1
10轮B	2
10轮B	3
10轮B	4
10轮B	5
10轮B	6
10轮B	7
10轮B	8
10轮B	9
10轮B	10
10轮C	1
10轮C	2
10轮C	3
10轮C	4
10轮C	5
10轮C	6
10轮C	7
10轮C	8
10轮C	9
10轮C	10
10轮C	11
10轮C	12
10轮C	13
10轮C	14
10轮C	15
posted on 2021-03-18 11:05  whn051799  阅读(62)  评论(0编辑  收藏  举报