zoukankan      html  css  js  c++  java
  • 锁 Lock、重入锁、写入锁

    ReentrantLock 重入锁 类似于synchronize 区别与写法上,在需要进行同步的代码部分加上锁定,但不要忘记最后一定要释放锁定,
    不然会造成锁永远无法释放,其他线程永远进不来的结果。
    eg:
     1 package com.zym.height.Lock01;
     2 
     3 import java.util.concurrent.locks.Lock;
     4 import java.util.concurrent.locks.ReentrantLock;
     5 
     6 public class UseReentrantLock {
     7     
     8     private Lock lock = new ReentrantLock();
     9     
    10     public void method1(){
    11         try {
    12             lock.lock();
    13             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method1..");
    14             Thread.sleep(1000);
    15             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method1..");
    16             Thread.sleep(1000);
    17         } catch (InterruptedException e) {
    18             e.printStackTrace();
    19         } finally {
    20             
    21             lock.unlock();
    22         }
    23     }
    24     
    25     public void method2(){
    26         try {
    27             lock.lock();
    28             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method2..");
    29             Thread.sleep(2000);
    30             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method2..");
    31             Thread.sleep(1000);
    32         } catch (InterruptedException e) {
    33             e.printStackTrace();
    34         } finally {
    35             
    36             lock.unlock();
    37         }
    38     }
    39     
    40     public static void main(String[] args) {
    41 
    42         final UseReentrantLock ur = new UseReentrantLock();
    43         Thread t1 = new Thread(new Runnable() {
    44             @Override
    45             public void run() {
    46                 ur.method1();
    47                 ur.method2();
    48             }
    49         }, "t1");
    50 
    51         t1.start();
    52         try {
    53             Thread.sleep(10);
    54         } catch (InterruptedException e) {
    55             e.printStackTrace();
    56         }
    57         //System.out.println(ur.lock.getQueueLength());
    58     }
    59     
    60     
    61 }
    View Code


    Lock Condition
    公平锁和非公平锁
    Lock lock = new ReentrantLock();    
    lock用法:
    tryLock():尝试获得锁(在给定的时间内尝试获得锁),获得结果用true/false返回。
    isFair():是否是公平锁。
    isLocked():是否锁定。
    getHoldCount():查询当前线程保持此锁的个数,也就是调用lock()次数。
    lockInterruptibly():优先响应中断的锁。
    getQueueLength():返回正在等待获取此锁的线程数。
    getWaitQueueLength():返回等待与锁定相关的给定条件Condition的线程数。
    hasQueuedThread(Thread thread):查询指定的线程是否正在等待此锁。
    hasQueuedThreads():查询是否有线程正在等待此锁。
    hasWaiters():查询是否有线程正在等待与此锁定有关的condition条件。
     1 package com.zym.height.Lock01;
     2 
     3 import java.util.concurrent.locks.Condition;
     4 import java.util.concurrent.locks.Lock;
     5 import java.util.concurrent.locks.ReentrantLock;
     6 
     7 public class UseCondition {
     8 
     9     private Lock lock = new ReentrantLock();
    10     private Condition condition = lock.newCondition();
    11     
    12     public void method1(){
    13         try {
    14             lock.lock();
    15             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入等待状态..");
    16             Thread.sleep(3000);
    17             System.out.println("当前线程:" + Thread.currentThread().getName() + "释放锁..");
    18             condition.await();    // Object wait
    19             System.out.println("当前线程:" + Thread.currentThread().getName() +"继续执行...");
    20         } catch (Exception e) {
    21             e.printStackTrace();
    22         } finally {
    23             lock.unlock();
    24         }
    25     }
    26     
    27     public void method2(){
    28         try {
    29             lock.lock();
    30             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..");
    31             Thread.sleep(3000);
    32             System.out.println("当前线程:" + Thread.currentThread().getName() + "发出唤醒..");
    33             condition.signal();        //Object notify
    34         } catch (Exception e) {
    35             e.printStackTrace();
    36         } finally {
    37             lock.unlock();
    38         }
    39     }
    40     
    41     public static void main(String[] args) {
    42         
    43         final UseCondition uc = new UseCondition();
    44         Thread t1 = new Thread(new Runnable() {
    45             @Override
    46             public void run() {
    47                 uc.method1();
    48             }
    49         }, "t1");
    50         Thread t2 = new Thread(new Runnable() {
    51             @Override
    52             public void run() {
    53                 uc.method2();
    54             }
    55         }, "t2");
    56         t1.start();
    57 
    58         t2.start();
    59     }
    60     
    61     
    62     
    63 }
    UseCondition
      1 package com.zym.height.Lock01;
      2 
      3 import java.util.concurrent.locks.Condition;
      4 import java.util.concurrent.locks.ReentrantLock;
      5 
      6 public class UseManyCondition {
      7 
      8     private ReentrantLock lock = new ReentrantLock();
      9     private Condition c1 = lock.newCondition();
     10     private Condition c2 = lock.newCondition();
     11     
     12     public void m1(){
     13         try {
     14             lock.lock();
     15             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m1等待..");
     16             c1.await();
     17             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m1继续..");
     18         } catch (Exception e) {
     19             e.printStackTrace();
     20         } finally {
     21             lock.unlock();
     22         }
     23     }
     24     
     25     public void m2(){
     26         try {
     27             lock.lock();
     28             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m2等待..");
     29             c1.await();
     30             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m2继续..");
     31         } catch (Exception e) {
     32             e.printStackTrace();
     33         } finally {
     34             lock.unlock();
     35         }
     36     }
     37     
     38     public void m3(){
     39         try {
     40             lock.lock();
     41             System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m3等待..");
     42             c2.await();
     43             System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m3继续..");
     44         } catch (Exception e) {
     45             e.printStackTrace();
     46         } finally {
     47             lock.unlock();
     48         }
     49     }
     50     
     51     public void m4(){
     52         try {
     53             lock.lock();
     54             System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
     55             c1.signalAll();
     56         } catch (Exception e) {
     57             e.printStackTrace();
     58         } finally {
     59             lock.unlock();
     60         }
     61     }
     62     
     63     public void m5(){
     64         try {
     65             lock.lock();
     66             System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
     67             c2.signal();
     68         } catch (Exception e) {
     69             e.printStackTrace();
     70         } finally {
     71             lock.unlock();
     72         }
     73     }
     74     
     75     public static void main(String[] args) {
     76         
     77         
     78         final UseManyCondition umc = new UseManyCondition();
     79         Thread t1 = new Thread(new Runnable() {
     80             @Override
     81             public void run() {
     82                 umc.m1();
     83             }
     84         },"t1");
     85         Thread t2 = new Thread(new Runnable() {
     86             @Override
     87             public void run() {
     88                 umc.m2();
     89             }
     90         },"t2");
     91         Thread t3 = new Thread(new Runnable() {
     92             @Override
     93             public void run() {
     94                 umc.m3();
     95             }
     96         },"t3");
     97         Thread t4 = new Thread(new Runnable() {
     98             @Override
     99             public void run() {
    100                 umc.m4();
    101             }
    102         },"t4");
    103         Thread t5 = new Thread(new Runnable() {
    104             @Override
    105             public void run() {
    106                 umc.m5();
    107             }
    108         },"t5");
    109         
    110         t1.start();    // c1
    111         t2.start();    // c1
    112         t3.start();    // c2
    113         
    114 
    115         try {
    116             Thread.sleep(2000);
    117         } catch (InterruptedException e) {
    118             e.printStackTrace();
    119         }
    120 
    121         t4.start();    // c1
    122         try {
    123             Thread.sleep(2000);
    124         } catch (InterruptedException e) {
    125             e.printStackTrace();
    126         }
    127         t5.start();    // c2
    128         
    129     }
    130     
    131     
    132     
    133 }
    UseManyCondition
     1 package com.zym.height.Lock01;
     2 
     3 import java.util.concurrent.locks.ReentrantLock;
     4 /**
     5  * lock.getHoldCount()方法:只能在当前调用线程内部使用,不能再其他线程中使用
     6  * 那么我可以在m1方法里去调用m2方法,同时m1方法和m2方法都持有lock锁定即可 测试结果holdCount数递增
     7  *
     8  */
     9 public class TestHoldCount {
    10 
    11     //重入锁
    12     private ReentrantLock lock = new ReentrantLock();
    13     
    14     public void m1(){
    15         try {
    16             lock.lock();
    17             System.out.println("进入m1方法,holdCount数为:" + lock.getHoldCount());
    18             
    19             //调用m2方法
    20             m2();
    21             
    22         } catch (Exception e) {
    23             e.printStackTrace();
    24         } finally {
    25             lock.unlock();
    26         }
    27     }
    28     
    29     public void m2(){
    30         try {
    31             lock.lock();
    32             System.out.println("进入m2方法,holdCount数为:" + lock.getHoldCount());
    33         } catch (Exception e) {
    34             e.printStackTrace();
    35         } finally {
    36             lock.unlock();
    37         }
    38     }
    39     
    40     
    41     public static void main(String[] args) {
    42         TestHoldCount thc = new TestHoldCount();
    43         thc.m1();
    44     }
    45 }
    Test HoldCondition
    
    


    ReentrantReadWriteLock

    读写锁 其核心就是实现读写分离的锁,在高并发访问下,尤其是读多写少的情况下,性能要远高于重入锁,在同一时间,只能有一个线程
          可以进行访问被锁定的代码,那么读写锁则不同,其本质是分层两个锁,即读锁、写锁。在读锁下,多个线程可以并发的进行访问,
          但是在写锁的时候,只能一个一个的顺序访问。
    口诀:读读共享,写写互斥,读写互斥。
     1 package com.zym.height.Lock01;
     2 
     3 import java.util.concurrent.locks.ReentrantReadWriteLock;
     4 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
     5 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
     6 
     7 public class UseReentrantReadWriteLock {
     8 
     9     private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    10     private ReadLock readLock = rwLock.readLock();
    11     private WriteLock writeLock = rwLock.writeLock();
    12     
    13     public void read(){
    14         try {
    15             readLock.lock();
    16             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
    17             Thread.sleep(3000);
    18             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
    19         } catch (Exception e) {
    20             e.printStackTrace();
    21         } finally {
    22             readLock.unlock();
    23         }
    24     }
    25     
    26     public void write(){
    27         try {
    28             writeLock.lock();
    29             System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
    30             Thread.sleep(3000);
    31             System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
    32         } catch (Exception e) {
    33             e.printStackTrace();
    34         } finally {
    35             writeLock.unlock();
    36         }
    37     }
    38     
    39     public static void main(String[] args) {
    40         
    41         final UseReentrantReadWriteLock urrw = new UseReentrantReadWriteLock();
    42         
    43         Thread t1 = new Thread(new Runnable() {
    44             @Override
    45             public void run() {
    46                 urrw.read();
    47             }
    48         }, "t1");
    49         Thread t2 = new Thread(new Runnable() {
    50             @Override
    51             public void run() {
    52                 urrw.read();
    53             }
    54         }, "t2");
    55         Thread t3 = new Thread(new Runnable() {
    56             @Override
    57             public void run() {
    58                 urrw.write();
    59             }
    60         }, "t3");
    61         Thread t4 = new Thread(new Runnable() {
    62             @Override
    63             public void run() {
    64                 urrw.write();
    65             }
    66         }, "t4");        
    67         
    68 //        t1.start();
    69 //        t2.start();
    70         
    71 //        t1.start(); // R 
    72 //        t3.start(); // W
    73         
    74         t3.start();
    75         t4.start();
    76         
    77         
    78         
    79         
    80         
    81         
    82         
    83         
    84     }
    85 }
    View Code















  • 相关阅读:
    solr服务中集成IKAnalyzer中文分词器、集成dataimportHandler插件
    Solr_全文检索引擎系统
    MySQL设置字段的默认值为当前系统时间
    mybatis_常用标签
    mybatis_映射查询
    Vue核心知识——computed和watch的细节全面分析
    nrm的安装与使用
    Windows下安装及使用NVM
    github仓库添加MIT许可
    ES6——箭头函数与普通函数的区别
  • 原文地址:https://www.cnblogs.com/john69-/p/6846435.html
Copyright © 2011-2022 走看看