首页 > 其他分享 >锁机制和信号量机制实现水果问题,同步机制

锁机制和信号量机制实现水果问题,同步机制

时间:2023-05-21 17:37:32浏览次数:40  
标签:plate 同步 Thread lock 信号量 while new 机制 public

使用Semaphore类实现

package com.huo.HelperClass.demo;

import sun.security.krb5.internal.TGSRep;

import java.util.concurrent.Semaphore;

/**
 * @version 1.0
 * @Author 作者名
 * @Date 2022/9/13 11:26
 */
//使用Semaphore实现水果同步问题
public class FruitDemo {

    public static void main(String[] args) {
        Semaphore plate = new Semaphore(1, true);
        Semaphore apple = new Semaphore(0, true);
        Semaphore orange = new Semaphore(0, true);

        Thread father = new Thread(()->{
            while (true) {
                try {
                    plate.acquire();
                    System.out.println(Thread.currentThread().getName()+" 放入一个苹果");
                    Thread.sleep(1000);
                    apple.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread mother = new Thread(()->{
            try {
                plate.acquire();
                System.out.println(Thread.currentThread().getName()+" 放入一个橘子");
                Thread.sleep(1000);
                orange.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread son = new Thread(()->{
            while (true) {
                try {
                    apple.acquire();
                    System.out.println( Thread.currentThread().getName() + " 拿走一个苹果");
                    Thread.sleep(1000);
                    plate.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread daughter = new Thread(() -> {
            while (true) {
                try {
                    orange.acquire();
                    System.out.println(Thread.currentThread().getName() + " 拿走一个橘子");
                    Thread.sleep(1000);
                    plate.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });

        father.setName("father");
        mother.setName("mother");
        son.setName("son");
        daughter.setName("daughter");


        father.start();
        mother.start();
        son.start();
        daughter.start();
    }
}

使用condition监视器实现

package com.huo.pc.fruitdemo;

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

/**
 * @version 1.0
 * @Author 作者名
 * @Date 2022/9/12 21:33
 */
/*
    妈妈生产橘子 orange = 0
    爸爸生产苹果 apple = 0
    儿子只吃苹果
    女儿只吃橘子
    有一个盘子 一个盘子只能放一个资源  plate = 1
 */
public class FruitDemo {

    public static void main(String[] args) {

        Fruit fruit = new Fruit();


        new Thread(()->{
            while (true) {
                fruit.motherPut();
            }
        },"妈妈").start();

        new Thread(()->{
            while (true) {
                fruit.daughterGet();
            }
        },"女儿").start();

        new Thread(()->{
            while (true) {
                fruit.fatherPut();
            }
        },"爸爸").start();

        new Thread(()->{
            while (true) {
                fruit.sonGet();
            }
        },"儿子").start();

    }
}


class Fruit {
    //初始化资源信号量
    private int plate = 1; //表示有一个盘子可以用
    private int apple = 0; //表示没有资源可以使用
    private int orange = 0;

    //锁和监视器
    Lock lock = new ReentrantLock();

    Condition father = lock.newCondition();
    Condition son = lock.newCondition();
    Condition mother = lock.newCondition();
    Condition daughter = lock.newCondition();


    /**
     * FatherPut
     */
    public void fatherPut(){
        lock.lock();
        try {
            //判断果盘是否为空
            while (plate == 0) {
                //等待
                father.await();
            }

            plate--;
            //放入一个苹果
            apple++;
            System.out.println(Thread.currentThread().getName() +" 生产了一个苹果");
            Thread.sleep(100);
            //通知儿子拿苹果
            son.signal();

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

    /**
     * sonGet
     */
    public void sonGet(){
        lock.lock();
        try {
            //判断苹果是否为空
            while (apple == 0) {
                //等待
                son.await();
            }

            plate++;
            //儿子拿苹果
            apple--;
            System.out.println(Thread.currentThread().getName() +" 拿走了一个苹果");
            Thread.sleep(100);

            //通知妈妈生产
            mother.signal();

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

    /**
     * motherPut
     */
    public void motherPut(){
        lock.lock();
        try {
            //判断果盘是否为空
            while (plate == 0) {
                mother.await();
            }

            plate--;
            //生产一个橘子
            orange++;
            System.out.println(Thread.currentThread().getName() +" 生产了一个橘子");
            Thread.sleep(100);

            //通知女儿拿橘子
            daughter.signal();

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

    /**
     * daughterGet
     */
    public void daughterGet(){
        lock.lock();
        try {
            //判断橘子是否为空
            while (orange == 0) {
                //等待
                daughter.await();
            }

            plate++;
            //拿走橘子
            orange--;
            System.out.println(Thread.currentThread().getName() +" 拿走了一个橘子");
            Thread.sleep(100);

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

class ThreadTest{
    public static void main(String[] args) {

        Da da = new Da();


        new Thread(() -> {

            da.printA();
        }, "A").start();
        new Thread(() -> {
            da.printC();
        }, "C").start();


    }


    static class Da{
        public synchronized void printA(){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName());
        }
        public  void printC(){
            System.out.println(Thread.currentThread().getName());
        }

    }
}

 

标签:plate,同步,Thread,lock,信号量,while,new,机制,public
From: https://www.cnblogs.com/qijiangforever/p/17418843.html

相关文章

  • 彻底掌握 MySQL InnoDB 的锁机制
    本文是对沈剑大佬锁机制十多篇文章的概括总结,文末有全部链接,还参考了10多位其他网友的优秀分享。1、概要MySQL中的锁可以按照粒度分为锁定整个表的表级锁(table-levellocking)和锁定数据行的行级锁(row-levellocking):表级锁具有开销小、加锁快的特性;但是表级锁的锁定粒度较大,发生......
  • 深入理解多核处理器的缓存一致性和通信机制
    操作系统级别的上下文切换操作系统级别的上下文切换是指当一个线程在执行过程中发生某种事件(如时间片用完、发生中断等),操作系统需要暂停当前线程的执行,保存其上下文(如寄存器状态、程序计数器、堆栈指针等),并切换到另一个线程继续执行的过程。这种上下文切换是由操作系统内核......
  • python内存管理机制
    1:引用计数机制实现垃圾回收对象引用一次,引用计数就增加1,销毁计数就减少1,当引用计数为零时,从内存中删除对象。还有一种情况,ab两对象互相引用时,del语句可以减少引用计数,但不会归零。会导致内存泄漏,解释器会定期执行一个循环检测,搜索不可访问对象的循环,并删除他们2:内存池机制为了......
  • 异常机制
    异常机制(Exception)实际工作中,遇到的情况不可能是非常完美的。比如:你写的某个模块,用户不一定符合你的要求,你的程序要打开某个文件,这个文件可能不存在或者文件格式不对,你要读取数据库的数据,数据可能是空的等。我们的程序再跑着,内存或硬盘可能就满了。等等。软件程序在运行过程中,非......
  • 【BSP视频教程】BSP视频教程第26期:CAN/CANFD/CANopen专题,CANFD整个运行机制精讲,图文并
     上期视频教程为大家分享了很多CAN理论方面的知识,本期视频教程我们在实战应用中学习CANFD。CANFD涉及到的知识点非常多,我们本期重点是把CANFD整个运行机制搞明白,知其然知其所以然。视频:https://www.bilibili.com/video/BV1iX4y117Bv视频提纲:参考资料:1、【原创】H7-TOOL的CANFDT......
  • 【BSP视频教程】BSP视频教程第26期:CAN/CANFD/CANopen专题,CANFD整个运行机制精讲,图文并
     上期视频教程为大家分享了很多CAN理论方面的知识,本期视频教程我们在实战应用中学习CANFD。CANFD涉及到的知识点非常多,我们本期重点是把CANFD整个运行机制搞明白,知其然知其所以然。视频:https://www.bilibili.com/video/BV1iX4y117Bv视频提纲:参考资料:1、【原创】H7-TOOL的CANFDT......
  • MyBatis 在大数据量下使用流式查询进行数据同步
    通常的数据同步中,如果数据量比较少的话可以直接全量同步,默认情况下,完整的检索结果集会将其存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于MySQL网络协议的设计,因此更易于实现。但是如果数据量很大的话,全量同步需要大量的内存,如果内存不足的话则可能会导致内存溢出。......
  • Java Semaphore 信号量详解
    Semaphore基本使用场景Semaphore的基本使用场景是限制一定数量的线程能够去执行.举个简单的例子:一个单向隧道能同时容纳10个小汽车或5个卡车通过(1个卡车等效与2个小汽车),而隧道入口记录着当前已经在隧道内的汽车等效比重.比如1个小汽车和1个卡车,则隧道入口显示3.若隧道......
  • JVM-垃圾回收机制
     JVM的垃圾回收机制——垃圾回收算法一、Java垃圾回收机制在java中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行执行。在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫描那些没有被任何......
  • 技术干货|如何利用 ChunJun 实现数据离线同步?
    ChunJun是⼀款稳定、易⽤、⾼效、批流⼀体的数据集成框架,基于计算引擎Flink实现多种异构数据源之间的数据同步与计算。ChunJun可以把不同来源、格式、特点性质的数据在逻辑上或物理上有机地集中,从⽽为企业提供全⾯的数据共享,目前已在上千家公司部署且稳定运⾏。在之前,我们曾......