xcode colors ros 打印 transactions NEJ Parsley jScrollPane vue前端开发 electron教程 mysql数据库名称 div外边距 ps字体旋转角度 matlab四舍五入 mysql升序 mysql更新多个字段 matlab 图像识别 idea中svn的使用 quartz配置 新手学c还是java maya曲线建模 destoon模板 网页设计公司 python3教程 python调用方法 python环境搭建 python中的zip python的编译器 python时间戳 python读取字典 java抽象类 java学习基础 java遍历集合 java接口规范 linux教程 脚本之家 千元以下最好的手机 id解锁大师 销售单软件 cg模宝 淘宝自动发货软件
当前位置: 首页 > 学习教程  > 编程语言

synchronized,Lock锁

2021/2/13 20:19:05 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

区别/*** synchronized 和 lock 的区别* 1. synchronized 是java内置关键字,Lock是java类* 2. synchronized 无法判断获取锁的状态,而Lock可以判断是否获取到了锁* 3. synchronized 会自动释放锁; Lock锁必须要手动释放锁,否则会发生死锁* 4.…

  • 区别
    /**
     * synchronized 和 lock 的区别
     * 1. synchronized 是java内置关键字,Lock是java类
     * 2. synchronized 无法判断获取锁的状态,而Lock可以判断是否获取到了锁
     * 3. synchronized 会自动释放锁; Lock锁必须要手动释放锁,否则会发生死锁
     * 4. synchronized 线程1 (获得锁 阻塞)、线程2(一直等待) || Lock锁可以tryLock获取锁的状态,不会一直等待
     * 5. synchronized 可重入锁,不可以终断,非公平 || Lock,可重入锁,可以判断锁,是否公平可以自己设置
     * 6. synchronized 适合少量的代码同步问题,Lock适合锁大量的同步代码。
     */
    

    不可重入锁:只判断这个锁有没有被锁上,只要被锁上了,那么无论当前申请锁的是已获取当前锁的线程还是未获得当前锁的线程,统统必须等待,实现较为简单。
    .
    可重入锁:不仅判断锁有没有被锁上,还会判断锁是谁锁上的,当上锁的就是当前请求锁的线程时,当前线程可以再次访问临界资源,并且把加锁次数加一。设计了加锁次数,以在解锁的时候,可以确保所有加锁的过程都解锁了,其他线程才能访问。不然没有加锁的参考值,也就不知道什么时候解锁?解锁多少次?才能保证本线程已经访问完临界资源了可以唤醒其他线程访问了。实现相对复杂。
    .
    总结:这个可重入的概念就是,拿到锁的线程可以多次以不用的方式再次访问临界资源而不出现死锁的情况。经典之处在于判断了当前申请锁的线程是否是加锁的线程。如果是,则拥有重(chong)入的能力
    .
    公平锁:十分公平,可以先来后到
    非公平锁:可以插队

  • 用synchronized实现售票问题

    synchronized 本质: 队列,锁

    public class SaleTicketSynchronized {
        public static void main(String[] args) {
            // 三个线程操作同一个资源,解耦
            Ticket ticket = new Ticket();
            // 多线程卖票, lombok表达式
            new Thread(() -> {
                for (int i = 0; i < 40; i++) {
                    ticket.sale();
                }
            }, "A").start();
            new Thread(() -> {
    
                for (int i = 0; i < 40; i++) {
                    ticket.sale();
                }
            }, "B").start();
            new Thread(() -> {
                for (int i = 0; i < 40; i++) {
                    ticket.sale();
                }
            }, "C").start();
        }
    }
    
    // 资源类
    class Ticket {
        private int ticketNums = 20;
        // 卖票, 传统同步的方式,
        // synchronized 本质: 队列,锁
        public synchronized void sale() {
            if (this.ticketNums > 0) {
                System.out.println(Thread.currentThread().getName() + "卖了" + (ticketNums--) + "票,还剩" + ticketNums + "张票");
    
            }
        }
    }
    
  • 用Lock锁实现售票问题

    创建锁(Lock lock = new ReentrantLock()) -> 加锁 -> 业务 -> 解锁

    public class SaleTicketLock {
        public static void main(String[] args) {
            Ticket2 ticket2 = new Ticket2();
            // 三个线程来售卖票
            new Thread(() -> {for (int i = 0; i < 30; i++) ticket2.sale();}, "A").start();
            new Thread(() -> {for (int i = 0; i < 30; i++) ticket2.sale();}, "B").start();
            new Thread(() -> {for (int i = 0; i < 30; i++) ticket2.sale();}, "C").start();
        }
    }
    
    // 资源类
    // 1. 创建lock锁
    // 2. 加锁
    // 3. 解锁
    class Ticket2 {
        private int ticketNums = 20;
        // 创建锁
        Lock lock = new ReentrantLock();
        // 售卖
        public void sale() {
            // 加锁
            lock.lock();
            try {
                // 业务代码
                if (ticketNums > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖了" + (ticketNums--) + "票,还剩" + ticketNums + "张票");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 解锁
                lock.unlock();
            }
        }
    }
    

本文链接: http://www.dtmao.cc/news_show_700439.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?