广州力科网站建设公司工信部网站备案电话

当前位置: 首页 > news >正文

广州力科网站建设公司,工信部网站备案电话,如何做网络推广工作,宁波外贸进出口公司目录 一、读写锁(ReentrantReadWriteLock) 二、非公平锁(synchronized/ReentrantLock) 三、可重入锁/递归锁(synchronized/ReentrantLock) 四、自旋锁(spinlock) 五、乐观锁/悲观锁 六、死锁 1、死锁代码 2、死锁的检测(jps -l 与 jstack 进程号) 七、sychronized-wait…目录 一、读写锁(ReentrantReadWriteLock) 二、非公平锁(synchronized/ReentrantLock) 三、可重入锁/递归锁(synchronized/ReentrantLock) 四、自旋锁(spinlock) 五、乐观锁/悲观锁 六、死锁 1、死锁代码 2、死锁的检测(jps -l 与 jstack 进程号) 七、sychronized-wait-notify 与 lock-await-signal的对比 1、sychronized与lock的对比 2、分组加锁的实例 本文通过学习周阳老师-尚硅谷Java大厂面试题第二季 总结的锁相关的笔记 一、读写锁(ReentrantReadWriteLock) import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock;class MyCache {private volatile MapString, Object map new HashMap();//volatile保证可见性private ReentrantReadWriteLock rwLock new ReentrantReadWriteLock();public void put(String key, Object value) {rwLock.writeLock().lock();//写锁创建try {System.out.println(Thread.currentThread().getName() \t 正在写入 key);try {// 模拟网络拥堵延迟0.3秒TimeUnit.MILLISECONDS.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}map.put(key, value);System.out.println(Thread.currentThread().getName() \t 写入完成);} catch (Exception e) {e.printStackTrace();} finally {rwLock.writeLock().unlock();//写锁释放}}public void get(String key) {rwLock.readLock().lock();//读锁创建try {System.out.println(Thread.currentThread().getName() \t 正在读取:);try {TimeUnit.MILLISECONDS.sleep(300);//模拟网络拥堵延迟0.3秒} catch (InterruptedException e) {e.printStackTrace();}Object value map.get(key);System.out.println(Thread.currentThread().getName() \t 读取完成 value);} catch (Exception e) {e.printStackTrace();} finally {rwLock.readLock().unlock();//读锁释放}}public void clean() {map.clear();//清空缓存} }public class ReadWriteLockDemo {public static void main(String[] args) {MyCache myCache new MyCache();for (int i 1; i 5; i) {//5个线程写final int tempInt i;//finalnew Thread(() - {myCache.put(tempInt , tempInt );}, String.valueOf(i)).start();}for (int i 1; i 5; i) {//5个线程读final int tempInt i;//finalnew Thread(() - {myCache.get(tempInt );}, String.valueOf(i)).start();}} } 二、非公平锁(synchronized/ReentrantLock) 定义区别非公平锁多个线程获取锁的顺序并不是按照申请锁的顺序有可能申请的线程比先申请的线程优先获取锁在高并发环境下有可能造成优先级翻转或者饥饿的线程也就是某个线程一直得不到锁比较粗鲁上来就直接尝试占有锁如果尝试失败就再采用类似公平锁那种方式公平锁多个线程按照申请锁的顺序来获取锁类似于排队买饭先来后到先来先服务就是公平的也就是队列很公平在并发环境中每个线程在获取锁时会先查看此锁维护的等待队列如果为空或者当前线程是等待队列中的第一个就占用锁否者就会加入到等待队列中以后安装FIFO的规则从队列中取到自己 synchronized是非公平锁ReentrantLock默认非公平锁 Lock lock new ReentrantLock(true);//默认false非公平锁true公平锁 三、可重入锁/递归锁(synchronized/ReentrantLock) synchronized可重入锁 ReentrantLock可重入锁
class MySynchronized {public synchronized void sendSMS() throws Exception{//发短信System.out.println(Thread.currentThread().getName() \t invoked sendSMS());sendEmail();//同步方法中调用另外一个同步方法}public synchronized void sendEmail() throws Exception{//发邮件System.out.println(Thread.currentThread().getId() \t invoked sendEmail());} } public class MyDemo {public static void main(String[] args) {MySynchronized mySynchronized new MySynchronized();new Thread(() - {try {mySynchronized.sendSMS();} catch (Exception e) {e.printStackTrace();}}, t1).start();new Thread(() - {try {mySynchronized.sendSMS();} catch (Exception e) {e.printStackTrace();}}, t2).start();} } /** t1 invoked sendSMS() t1 invoked sendEmail() t2 invoked sendSMS() t2 invoked sendEmail() */ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;class MyReentrantLock implements Runnable{Lock lock new ReentrantLock();Overridepublic void run() {method1();}public void method1() {lock.lock();try {System.out.println(Thread.currentThread().getName() \t exe method1);method2();} finally {lock.unlock();}}public void method2() {lock.lock();try {System.out.println(Thread.currentThread().getName() \t exe method2);} finally {lock.unlock();}} } public class ReenterLockDemo {public static void main(String[] args) {MyReentrantLock myReentrantLock new MyReentrantLock();Thread t1 new Thread(myReentrantLock, t1);Thread t2 new Thread(myReentrantLock, t2);t1.start();t2.start();} } /** t1 exe method1 t1 exe method2 t2 exe method1 t2 exe method2 */ 四、自旋锁(spinlock) public class SpinLockDemo {// 现在的泛型装的是Thread原子引用线程AtomicReferenceThread atomicReference new AtomicReference();public void myLock() {//加锁Thread thread Thread.currentThread();System.out.println(Thread.currentThread().getName() \t come in );//开始自旋期望值是null更新值是当前线程如果是null则更新为当前线程否者自旋while(!atomicReference.compareAndSet(null, thread)) {}}public void myUnLock() {//解锁Thread thread Thread.currentThread();//自己用完了后把atomicReference变成nullatomicReference.compareAndSet(thread, null);System.out.println(Thread.currentThread().getName() \t invoked myUnlock());}public static void main(String[] args) {SpinLockDemo spinLockDemo new SpinLockDemo();new Thread(() - {spinLockDemo.myLock();//加锁try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}spinLockDemo.myUnLock();//释放锁}, t1).start();//1秒后启动t2线程占用锁try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}new Thread(() - {spinLockDemo.myLock();//加锁spinLockDemo.myUnLock();//释放锁}, t2).start();} } /** t1 come in …..五秒后….. t1 invoked myUnlock() t2 come in t2 invoked myUnlock() */ 首先输出的是 t1 come in然后1秒后t2线程启动发现锁被t1占有然后不断执行compareAndSet方法来进行比较直到t1释放锁后也就是5秒后t2成功获取到锁然后释放   五、乐观锁/悲观锁 1、MybatisPlus使用乐观锁的3步走 step1、在数据库增加version字段默认为1 step2、在实体类增加对应的字段     Version     private Integer version; step3、注册乐观锁在MybatisPlusConfig中配置     Bean     public OptimisticLockerInterceptor optimisticLockerInterceptor() {         return new OptimisticLockerInterceptor();     } 2、悲观锁 六、死锁 1、死锁代码 import java.util.concurrent.TimeUnit;class HoldLockThread implements Runnable{private String lockA;private String lockB;public HoldLockThread(String lockA, String lockB) {this.lockA lockA;this.lockB lockB;}Overridepublic void run() {synchronized (lockA) {System.out.println(Thread.currentThread().getName() \t 自己持有 lockA \t 尝试获取 lockB);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lockB) {System.out.println(Thread.currentThread().getName() \t 自己持有 lockB \t 尝试获取 lockA);}}} }public class DeadLockDemo {public static void main(String[] args) {String lockA lockA;String lockB lockB;new Thread(new HoldLockThread(lockA, lockB), t1).start();new Thread(new HoldLockThread(lockB, lockA), t2).start();} } /** t1 自己持有lockA 尝试获取lockB t2 自己持有lockB 尝试获取lockA */2、死锁的检测(jps -l 与 jstack 进程号) step1、jps -l step2、jstack 7560   #后面参数是jps输出的该类的pid 查看最后一行我们看到 Found 1 deadlock即存在一个死锁  七、sychronized-wait-notify 与 lock-await-signal的对比 sychronized   -     wait         -    notifylock                -   await         -    signal1、sychronized与lock的对比 sychronizedlock1.定义JVM层面的java关键字底层是通过monitor对象来完成api层面的锁底层是JUC锁(java.util.concurrent.locks.Lock)2.使用方法不需要用户去手动释放锁系统自动释放需要用户去手动释放锁若没有主动释放锁就有可能出现死锁的现象需要lock() 和 unlock() 配置try catch语句来完成3.等待是否中断不可中断 可中断可以设置超时方法 设置超时方法trylock(long timeout, TimeUnit unit) lockInterrupible() 放代码块中调用interrupt() 方法可以中断 4.加锁是否公平非公平锁 默认非公平锁构造函数可以传递boolean值true为公平锁false为非公平锁 锁绑定多个条件Condition没有要么随机要么全部唤醒可以精确唤醒 2、分组加锁的实例 题目多线程之间按顺序调用实现 A- B - C 三个线程启动要求如下 AA打印5次BB打印10次CC打印15次 紧接着 AA打印5次BB打印10次CC打印15次 .. 来10轮 分析链式唤醒的操作适合用lock class ShareResource {private int number 1;//A1B2c3private Lock lock new ReentrantLock();//可重入锁// 这三个相当于备用钥匙private Condition condition1 lock.newCondition();private Condition condition2 lock.newCondition();private Condition condition3 lock.newCondition();public void print5() {lock.lock();try {//step1、判断while(number ! 1) condition1.await();//step2、干活for (int i 0; i 5; i) {System.out.println(Thread.currentThread().getName() \t number \t i);}// step3、唤醒,通知B线程执行number 2;condition2.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void print10() {lock.lock();try {//step1、判断while(number ! 2) condition2.await();//step2、干活for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() \t number \t i);}//step3、唤醒通知C线程执行number 3;condition3.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void print15() {lock.lock();try {//step1、判断while(number ! 3) condition3.await();//step2、干活for (int i 0; i 15; i) {System.out.println(Thread.currentThread().getName() \t number \t i);}//step3、唤醒通知A线程执行number 1;condition1.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}} }public class SyncAndReentrantLockDemo {public static void main(String[] args) {ShareResource shareResource new ShareResource();new Thread(() - {for (int i 0; i 10; i) {shareResource.print5();}}, A).start();new Thread(() - {for (int i 0; i 10; i) {shareResource.print10();}}, B).start();new Thread(() - {for (int i 0; i 10; i) {shareResource.print15();}}, C).start();} }