【JAVA多线程编程核心技术】第四章 Lock(ReentrantLock)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chuxue1989/article/details/88421687

一、ReentrantLock简介

ReentrantLock:可重入锁。

  • 分路分支通知功能
package com.hfview.reentrantLock.base;

import java.util.concurrent.locks.ReentrantLock;

/**
 * ReentrantLock的基本使用
 *
 * @author: zhw
 * @since: 2019/3/12 11:41
 */
public class Demo1 {

    public static void main(String[] args) {

        final ReentrantLock lock = new ReentrantLock();

         new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    lock.lock();
                    System.out.println("a begin");

                    Thread.sleep(2000);

                    System.out.println("a end");
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    lock.lock();
                    System.out.println("b begin");

                    Thread.sleep(2000);

                    System.out.println("b end");
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();

    }

}

使用分为2步,第一步lock锁定 第二步unlock解锁

二、ReentrantLock分路分支通知功能

下面就是演示如何解决notifyAll浪费性能的问题

package com.hfview.reentrantLock;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 修改多消费者和生产者
 *
 * @author: zhw
 * @since: 2019/3/12 11:50
 */
public class Demo2 {


    public static void main(String[] args) {

        Service service = new Service();


        for(int i=0;i<20;i++){
            Produce p = new Produce(service);

            Consumer c = new Consumer(service);

            p.start();
            c.start();
        }


    }


}

class Service{

    private ReentrantLock lock = new ReentrantLock();

    private Condition pCondition = lock.newCondition();

    private Condition sCondition = lock.newCondition();

    private List<String> list = new ArrayList<>();

    public void push(){
        try {
            lock.lock();
            while(list.size()>0){
                pCondition.await();
            }

            list.add("zhw");

            System.out.println("push zhw :"+Thread.currentThread().getName());

            sCondition.signal();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }


    public void pop(){
        try {
            lock.lock();
            while(list.size()==0){
                sCondition.await();
            }

            list.remove(0);

            System.out.println("        pop zhw :"+Thread.currentThread().getName());

            pCondition.signal();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

}

class Produce extends Thread{

    private Service service;

    public Produce(Service service){
        this.service = service;
    }

    @Override
    public void run(){
        service.push();
    }
}

class Consumer extends  Thread{

    private Service service;

    public Consumer(Service service){
        this.service = service;
    }

    @Override
    public void run(){
        service.pop();
    }

}

三、ReentrantLock公平锁和非公平锁

简单来说就是先进先出

package com.hfview.reentrantLock.Fair;


import java.lang.invoke.LambdaConversionException;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 公平锁和非公平锁
 * @author: zhw
 * @since: 2019/3/12 14:18
 */
public class Service implements Runnable{

    private final ReentrantLock lock;

    public Service(boolean isFair){
        lock = new ReentrantLock(isFair);
    }

    @Override
    public void run(){

        try {
            System.out.println("线程:"+Thread.currentThread().getName()+" 运行了");

            lock.lock();

            System.out.println("    线程:"+Thread.currentThread().getName()+" 获得了锁");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }


    public static void main(String[] args) {
        Service service = new Service(true);

        Thread[] arr = new Thread[20];

        for(int i=0;i<20;i++){
            arr[i] = new Thread(service);
        }

        for(Thread t:arr){
            t.start();
        }
    }
}

在这里插入图片描述
公平锁: 顾名思义,先来排队的先去获得锁。就行食堂吃饭

非公平锁: 看CPU心情随机的去获得锁,默认是非公平的(残忍的人生啊)

四、ReentrantReadWriteLock锁

该锁是ReentrantLock的一种改进,这是读写分离的思想,都是读的时候是可以共享锁的,是读读 或者是读写 就要设计到写都要是互斥锁。

package com.hfview.reentrantReadWriteLock.read;

import java.io.Serializable;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * //TODO 写注释
 *
 * @author: zhw
 * @since: 2019/3/12 15:08
 */
public class Demo1 {

    public static void main(String[] args) {

        Service service = new Service();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                service.read1();
                //service.write1();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                //service.read2();
                service.write2();
            }
        });

        t1.start();
        t2.start();

    }


}






class Service {

    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read1() {
        try {

            /**
             * 共享读锁
             */
            lock.readLock().lock();
            System.out.println(Thread.currentThread().getName()+" 获得read锁 "+System.currentTimeMillis());

            Thread.sleep(2000);
        }catch (Exception e){

        }finally {
            lock.readLock().unlock();
        }
    }

    public void read2() {
        try {

            lock.readLock().lock();

            System.out.println(Thread.currentThread().getName()+" 获得read锁 "+System.currentTimeMillis());

            Thread.sleep(2000);
        }catch (Exception e){

        }finally {
            lock.readLock().unlock();
        }
    }


    public void write1() {
        try {

            lock.writeLock().lock();

            System.out.println(Thread.currentThread().getName()+" 获得write锁 "+System.currentTimeMillis());

            Thread.sleep(2000);
        }catch (Exception e){

        }finally {
            lock.writeLock().unlock();
        }
    }

    public void write2() {
        try {

            lock.writeLock().lock();

            System.out.println(Thread.currentThread().getName()+" 获得write锁 "+System.currentTimeMillis());

            Thread.sleep(2000);
        }catch (Exception e){

        }finally {
            lock.writeLock().unlock();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/chuxue1989/article/details/88421687