学习wait、notify和synchronized及Lock

今天暂时把理论放这里,后续补充代码实践:

 1 package com.cheng2839.test;
 2 
 3 import java.util.concurrent.locks.Lock;
 4 import java.util.concurrent.locks.ReadWriteLock;
 5 import java.util.concurrent.locks.ReentrantLock;
 6 import java.util.concurrent.locks.ReentrantReadWriteLock;
 7 
 8 /**
 9  * Lock学习
10  */
11 public class MyTest011 {
12 
13     public void packageClaList() {
14         //学习包 java.util.concurrent.locks. 下的类
15 
16         /**
17          * 获取锁:
18          * lock()     无返回值
19          * tryLock()   有返回值
20          * tryLock(long time, TimeUnit unit)   在一定时间内获取锁
21          * lockInterruptibly()  未获取到锁,会响应中断(抛出异常)
22          *
23          * 释放锁:
24          * unLock()
25          */
26 
27         // ReentrantLock: 可重入锁 唯一实现Lock接口
28         Lock lock = new ReentrantLock();
29 
30         /**
31          * ReadWriteLock: 读写锁 接口
32          *
33          * ReentrantReadWriteLock: 实现类
34          * readLock():获取读锁
35          * writeLock():获取写锁
36          */
37         ReadWriteLock rwLock = new ReentrantReadWriteLock();
38         rwLock.readLock().lock();
39         //如果有一个线程已经占用了读锁,则此时其他线程要申请读锁,也可以同时获取到读锁。
40         //如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。
41         //如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
42 
43 
44         /**
45          * Lock和synchronized有以下几点不同:
46          *
47          * 1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
48          * 2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;
49          *    而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,
50          *    因此使用Lock时需要在finally块中释放锁;
51          * 3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,
52          *    等待的线程会一直等待下去,不能够响应中断;
53          * 4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
54          * 5)Lock可以提高多个线程进行读操作的效率。
55          *
56          * 在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),
57          * 此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。
58          */
59 
60         /**
61          * 1. 可重入锁
62          * 如果锁具备可重入性,则称作为可重入锁。像synchronized和ReentrantLock都是可重入锁,
63          * 可重入性实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。
64          * 举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。
65          * 简单的理解:线程已经具备锁,不必再申请锁,可一直执行完毕。
66          *
67          * 2. 可中断锁
68          * 在Java中,synchronized就不是可中断锁,而Lock是可中断锁。
69          *
70          * 3. 公平锁
71          * 公平锁即尽量以请求锁的顺序来获取锁。
72          * synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。
73          * 而对于ReentrantLock和ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。
74          * ReentrantLock中静态内部类:1)NotFairSync实现非公平锁;2)FairSync实现公平锁
75          * ReentrantLock lock = new ReentrantLock(true); 参数为true表示为公平锁,为fasle为非公平锁
76          *
77          * 4. 读写锁
78          * 正因为有了读写锁,才使得多个线程之间的读操作不会发生冲突。
79          *  ReadWriteLock就是读写锁,它是一个接口,ReentrantReadWriteLock实现了这个接口。
80          *  可以通过readLock()获取读锁,通过writeLock()获取写锁。
81          */
82 
83 
84         /**
85          * Object下的锁:
86          * wait():释放占有的对象锁
87          * notify(): 该方法会唤醒因为调用对象的wait()而等待的线程
88          * notifyAll()则是唤醒所有等待的线程
89          *
90          * 学习地址:https://www.cnblogs.com/fenjyang/p/11603229.html
91          */
92     }
93 
94 
95 }

猜你喜欢

转载自www.cnblogs.com/cheng2839/p/12721519.html
今日推荐