java--Lock接口

Lock接口

1. 介绍

与synchronized相比,Lock显示锁的定义,结构更加灵活。
提供更多的实用性方法,功能更强大,性能更好一些。

常用方法

void lock() //获取锁,如果锁被占用,就等待
boolean tryLock() //尝试获取锁,成功就返回true
void unlock() //释放锁

2. Lock接口的实现类一般是ReentrantLock(常用)

案例,四个窗口共卖一百张票。

步骤

1. 创建卖一百张票的任务
2. 用四个线程去执行


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

public class TestLock {

    public static void main(String[] args) {

        //创建任务

        Runnable sellTicket = new Runnable() {

            //定义锁
            private Lock lock = new ReentrantLock();

            //定义票
            private int ticket = 100;

            @Override
            public void run() {

                while (true) {
                    lock.lock();
                    try {
                        if (ticket <= 0) {
                            break;
                        }

                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        System.out.println(Thread.currentThread().getName() + "正在售卖第" + ticket + "张票");
                        this.ticket--;
                    } finally {
                        lock.unlock();
                    }
                }
            }
        };

        ExecutorService es = Executors.newFixedThreadPool(4);

        for (int i = 0; i < 4; i++){
            es.submit(sellTicket);
        }

        es.shutdown();
        while (es.isTerminated()){}


    }

}

结果:
在这里插入图片描述

3. 补充ReadWriteLock接口

其实例类如下所示ReentrantReadWriteLock(用于读写环境的情况下,效率更高)
ReentrantReadWriteLock是一种支持一写多读的同步锁,读写分离,可分别分配读锁和写锁。
支持多次分配读锁,使多个读操作可以并发执行。

写--写:互斥,阻塞
读--写:互斥,读阻塞写、写阻塞读
读--读:不互斥,不阻塞

有点: 在读操作远远多于,写操作的时候,可以提高效率。

案例 一个变量value需要被18个线程进行读操作,2个线程进行写操作。

思路:

1. 创建一个读写类ReadWrite,里面还有一个变量value,一个锁lock。
2. 实现value的get以及set方法,方法内部在针对变量value的修改或者读取的时候,需要加上锁。
3. 在主函数里,创建两个任务,分别用来调用ReadWrite里面实现的读写方法。
4. 创建线程池,容量为20,将读写任务分别提交。

代码

/*
** ReadWrite类
*/

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

public class ReadWrite {

    private ReadWriteLock lock = new ReentrantReadWriteLock();

    private int value;

    public int getValue() {

        lock.readLock().lock();
       try {
         //延缓输出
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           
           return value;
           
       }
       finally {
           lock.readLock().unlock();
       }

    }

    public void setValue(int value) {
        lock.writeLock().lock();
        try {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.value = value;
        }
        finally {
            lock.writeLock().unlock();
        }
    }
}

主函数

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

public class TestReentrantReadWriteLock {

    public static void main(String[] args) {

        //实例化对象
        ReadWrite readWrite = new ReadWrite();
        //创建线程池
        ExecutorService es = Executors.newFixedThreadPool(20);

        //写需要完成的任务
        Runnable write = new Runnable() {
            @Override
            public void run() {
                int n = new Random().nextInt(100);
                readWrite.setValue(n);
                System.out.println(Thread.currentThread().getName() + "正在写入----" + n);
            }
        };
        Runnable read = new Runnable() {
            @Override
            public void run() {
                int n = readWrite.getValue();
                System.out.println(Thread.currentThread().getName() + "正在读出----" + n);
            }
        };

        long start = System.currentTimeMillis();
        //将任务放到线程池里面
        for(int i = 0;i < 15; i++){
            es.submit(write);
        }

        for (int i = 0; i < 5; i++){
            es.submit(read);
        }
        es.shutdown();

        while (!es.isTerminated()){}

        long end  = System.currentTimeMillis();

        System.out.println("耗费时间为--" + (end - start));

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沙丁鱼w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值