• ReentrantLock API


      java可重入锁,简单几个小案例,测试特性。

       1.尝试锁  tryLock

    package com.cn.cfang.ReentrantLock;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Test02 {
    
        private Lock lock = new ReentrantLock();
        
        private void m1(){
            try{
                lock.lock();
                for(int i = 0; i < 10; i++){
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("m1() method " + i);
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
        
        private void m2(){
            boolean isLocked = false;
            try {
                //尝试锁,如果已被其他线程锁住,无法获取锁标记,则返回false
                //相反,如果获取锁标记,则返回true
                //isLocked = lock.tryLock();
                
                //阻塞尝试锁:会阻塞参数代表的时长,再去尝试获取锁标记
                //如果超时未获取,不继续等待,直接返回false
                //阻塞尝试锁类似于自旋锁。
                isLocked = lock.tryLock(11, TimeUnit.SECONDS);
                if(isLocked){
                    System.out.println("method m2 synchronized");
                }else{
                    System.out.println("method m2 unsynchronized");
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(isLocked){
                    lock.unlock();
                }
            }
        }
        
        public static void main(String[] args) {
            Test02 t = new Test02();
            
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m1();
                }
            }).start();
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m2();
                }
            }).start();
        }
    }

      2. 可中断

    package com.cn.cfang.ReentrantLock;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * ReentrantLock的可打断性
     * 
     * 打断 : 调用thread.interrupt()方法,可打断线程阻塞状态,抛出异常。
     * 可尝试打断,阻塞等待锁。
     * 
     * 阻塞状态 :包括普通阻塞状态,等待队列,锁池队列
     * 普通阻塞 : sleep,可以被打断。
     * 等待队列 : wait方法调用,也是一种阻塞状态,不能被打断,只能等待notify
     * 锁池队列 : 无法获取锁标记。不是所有的锁池队列都能被打断
     *         ReentrantLock的lock获取锁标记的时候,如果未获取,需要阻塞的去等待锁标记,无法被打断
     *         ReentrantLock的lockInterruptibly获取锁标记的时候,如果未获取,需要阻塞等待,可以被打断
     * 
     * @author cfang
     * 2018年5月4日 下午2:23:41
     */
    public class Test03 {
    
        private Lock lock = new ReentrantLock();
        
        private void m1(){
            try {
                lock.lock();
                for(int i = 0; i < 5; i++){
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("m1() method " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
        
        private void m2(){
            try {
                lock.lockInterruptibly(); //可尝试打断,阻塞等待锁,可以被其他的线程打断阻塞状态
                System.out.println("m2() method");
            } catch (InterruptedException e) {
    //            e.printStackTrace();
            }finally{
                //可能异常打断,所以释放锁标记必须进行异常处理
                try {
                    lock.unlock();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
        
        public static void main(String[] args) {
            Test03 t = new Test03();
            
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m1();
                }
            }).start();
            
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m2();
                }
            });
            t2.start();
            
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t2.interrupt(); //打断线程休眠阻塞等待。非正常结束阻塞状态的线程,都会抛出异常。
        }
    }

      3. 公平锁 : ReentrantLock可定义公平锁,多个线程竞争锁标记的时候,公平锁会记录等待时长,当前线程执行结束后,会优先选取等待时长最长的线程,去获取锁标记执行。

        synchronized不具有此特性。

     1 package com.cn.cfang.ReentrantLock;
     2 
     3 import java.util.concurrent.TimeUnit;
     4 import java.util.concurrent.locks.Lock;
     5 import java.util.concurrent.locks.ReentrantLock;
     6 
     7 public class Test04 {
     8 
     9     public static void main(String[] args) {
    10         TestReentrantlock t = new TestReentrantlock();
    11         new Thread(t).start();
    12         new Thread(t).start();
    13     }
    14     
    15 }
    16     
    17 class TestReentrantlock implements Runnable{
    18     
    19     private Lock lock = new ReentrantLock(true); //加参数true,代表公平锁 
    20     @Override
    21     public void run() {
    22         for (int i = 0; i < 5; i++) {
    23             lock.lock();
    24             try {
    25                 System.out.println(Thread.currentThread().getName() + " get lock");
    26             }finally{
    27                 lock.unlock();
    28             }
    29         }
    30     }
    31 }
  • 相关阅读:
    关于__attribute__[转]
    Boost Posix Time
    c++ explicit构造函数[转]
    C++11 多线程:数据保护[转]
    C++ int,char,string,CString类型转换(整理总结)
    C和C++如何来编写时间的程序[转]
    设置CentOS防火墙开放端口
    SSH框架
    20060518: Alert!
    yum命令时出现Error: xz compression not available问题。
  • 原文地址:https://www.cnblogs.com/eric-fang/p/8991208.html
Copyright © 2020-2023  润新知