• 同步锁Lock & 生产者和消费者案例


    显示锁 Lock

    ①在 Java 5.0 之前,协调共享对象的访问时可以使用的机 制只有 synchronized 和 volatile 。

       Java 5.0 后增加了一些 新的机制,但并不是一种替代内置锁的方法,

       而是当内置锁不适用时,作为一种可选择的高级功能。

    ②ReentrantLock 实现了 Lock 接口,并提供了与 synchronized 相同的互斥性和内存可见性。

       但相较于 synchronized 提供了更高的处理锁的灵活性。

    TestLock

    package com.aff.juc;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    /*
    synchronized:隐式锁
      1.同步代码快
      2.同步锁
      jdk 1.5后
      3.同步锁Lock
        注意:是一个显示锁,需要lock()方法上锁,必须通过unlock()方法进行释放锁
     */
    
    public class TestLock {
        public static void main(String[] args) {
            Ticket t = new Ticket();
            Thread t1 = new Thread(t,"窗口1");
            Thread t2 = new Thread(t,"窗口2");
            Thread t3 = new Thread(t,"窗口3");
            Thread t4 = new Thread(t,"窗口4");
    
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
    }
    
    class Ticket implements Runnable {
        private int tick = 10000;
        private Lock lock = new ReentrantLock();
    
        @Override
        public void run() {
            while (true) {
                lock.lock();// 先上锁
                try {
                    if (tick > 0) {
                        Thread.sleep(10);
                        System.out.println(Thread.currentThread().getName() + "还剩票数" + --tick);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();// 执行完得解锁,必须执行 放在finally中
                }
            }
        }
    }

    生产者和消费者案例,等待唤醒机制

    TestProductorAndConsumer

    package com.aff.juc;
    
    //生产者消费者案例,等待唤醒机制
    public class TestProductorAndConsumer {
        public static void main(String[] args) {
            Clerk clerk = new Clerk();
            Productor pro = new Productor(clerk);
            Consumer cus = new Consumer(clerk);
    
            new Thread(pro, "生产者A").start();
            new Thread(cus, "消费者B").start();
            new Thread(pro, "生产者C").start();
            new Thread(cus, "消费者D").start();
        }
    
    }
    
    // 店员
    class Clerk {
        private int product = 0;
    
        // 进货
        public synchronized void get() {
            while (product >= 1) {//为了避免虚假唤醒问题,应该总是使用在循环中
                System.out.println("产品已满");
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + ":" + ++product);
            this.notifyAll();
    
        }
    
        // 卖货
        public synchronized void sale() {
            while (product <= 0) {
                System.out.println("缺货");
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + ":" + --product);
            this.notifyAll();
    
        }
    }
    
    // 生产者
    class Productor implements Runnable {
        private Clerk clerk;
    
        public Productor(Clerk clerk) {
            this.clerk = clerk;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                try {
                    Thread.sleep(200);
                } catch (Exception e) {
                }
                clerk.get();
            }
        }
    }
    
    // 消费者
    class Consumer implements Runnable {
        private Clerk clerk;
    
        public Consumer(Clerk clerk) {
            this.clerk = clerk;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                clerk.sale();
            }
        }
    }
    All that work will definitely pay off
  • 相关阅读:
    Spring格式化注解
    Mysql 慢查询和慢查询日志分析
    jQuery中的end()方法
    webService学习笔记
    让Hibernate和触发器协同工作
    JavaScript中的setInterval用法
    jQuery中事情的动态绑定
    mongoDB如何处理多对多关系
    新生儿信息管理系统在线帮助
    MySQL数据库安装与配置详解
  • 原文地址:https://www.cnblogs.com/afangfang/p/12631964.html
Copyright © 2020-2023  润新知