Java-Lock接口、重入锁、读写锁

一、Lock接口

  Lock接口是JDK1.5加入的,与synchronized比较,显示定义,结构更灵活

  提供更多实用性方法,功能更强大、性能更优越

  常用方法:

    void lock();//获取锁,如果锁被占用,则等待

    boolean tryLock()//尝试获取锁(成功返回true,失败返回false,不阻塞)

    void unlock()//释放锁

       

二、重入锁

  ReentrantLock:Lock接口的实现类,与synchronized一样具有互斥锁功能。

  案例:重入锁 ReentrantLock 的使用

package com.monv.chatper14_1;
/**
 * 重入锁 ReentrantLock的使用
 */
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyList {
    
    private String[] str = {"A","B","","",""};
    private int count = 2;
    
    //创建锁
    private Lock lock = new ReentrantLock();
    //添加元素
    public void add(String value) {
        lock.lock();
        try {
            str[count] = value;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"添加了"+value);
            count++;
        } finally {
            lock.unlock();
        }
    }
    public String[] getStr() {
        return str;
    }
}
--------------------测试--------------------------------------
package com.monv.chatper14_1;

import java.util.Arrays;

public class TestMyList {
    public static void main(String[] args) throws Exception{
        MyList list1 = new MyList();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                list1.add("Hello");
            }
        };
        Runnable runnable2 = new Runnable() {
            
            @Override
            public void run() {
                list1.add("World");
            }
        };
        //定义线程
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable2);
        //启动线程
        t1.start();
        t2.start();
        
        t1.join();
        t2.join();
        
        System.out.println(Arrays.toString(list1.getStr()));
    }
}
---------------------------------------

  案例2:卖票的案例

package com.monv.chatper14_1;
/**
 * 卖票案例
 * @author Monv
 *
 */

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ticket implements Runnable{
    private int ticket = 100;
    private Lock lock = new ReentrantLock ();
    @Override
    public void run() {
        while(true) {
            lock.lock();
            try {
                if (ticket<=0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"卖了第"+ticket+"张票");
                ticket--;
            } finally {
                lock.unlock();
            }
        }
    }
}
-----------------------------测试------------------------------
package com.monv.chatper14_1;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestTicket {
    public static void main(String[] args) {
        Ticket tk = new Ticket();
        //用线程池的方法卖票
        //创建一个线程池
        ExecutorService es = Executors.newFixedThreadPool(4);
        for (int i =0;i<4;i++) {
            es.submit(tk);
        }
        es.shutdown();
    }
}
--------------------------------------------------------------

 

三、读写锁

  ReentrantReadWriteLock:

    一种支持一写多读的同步锁,读写分离,可分别分配读锁、写锁。

    支持多次分配读锁,使多个读操作可以并发执行。

  互斥规则:

    写——写:互斥、堵塞

    读——写:互斥,读堵塞写、写堵塞读

    读——读:不互斥、不阻塞

    在读操作远远高于写操作的环境中,可在保障线程安全的情况下,提高运行效率

    es.isTerminated() : 判断线程是否全部执行完毕

  案例:读写锁的使用

package com.monv.chatper14_1;
/**
 * 演示读写锁的使用
 * ReentrantReadWriteLock
 * @author Monv
 *
 */

import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

public class ReadWriteDemo {
    //1.创建读写锁
    private ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();
    //创建读锁
    private ReadLock readl = rrwl.readLock();
    //创建写锁
    private WriteLock writel = rrwl.writeLock();
    
    private String value;
    //写入
    public void setValue(String value) {
        writel.lock();
        try {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("写入操作:"+value);
            this.value = value;
        }
        finally {
            writel.unlock();
        }
    }
    //读取
    public String getValue() {
        readl.lock();
        try {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("读取操作:"+this.value);
            return this.value;
        } finally {
            readl.unlock();
        }    
    }
}
---------------------------测试----------------------------
package com.monv.chatper14_1;
/**
 * 读写锁
 */
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestReadWrite {
    public static void main(String[] args) {
        ReadWriteDemo rwd = new ReadWriteDemo();
        //创建线程池 
        ExecutorService es = Executors.newFixedThreadPool(20);
        //两个功能写和读
        Runnable write = new Runnable() {
            @Override
            public void run() {
                rwd.setValue("这是一个写的操作");
            }
        };
        Runnable read  = new Runnable() {
            @Override
            public void run() {
                rwd.getValue();
            }
        };
        
        long beg = System.currentTimeMillis();
        //分配2个写的任务
        for (int i =0;i<2;i++) {
            es.submit(write);    
        }
        //分配18个读的任务
        for(int i = 0;i<18 ;i++) {
            es.submit(read);
        }
        //结束线程池
        es.shutdown();
        while (!es.isTerminated()) {//如果线程未全部结束,则空转等待
        }
        long end = System.currentTimeMillis();
        System.out.println("用时:"+(end  - beg  ));
    }
}
-----------------------------------------------------------

 

posted @ 2021-01-19 21:39  改Bug的小魔女  阅读(150)  评论(0编辑  收藏  举报