那些年的Java开发经验记录

news2025/6/20 5:37:15

Java同步锁(浅显易懂,精简讲解)

详细讲解可以看这篇文章Java对象锁和类锁全面解析(多线程synchronized关键字)

精简如下:

1.不管什么锁,都是属于对象锁(类也是一种对象)

2.一个对象只有一个锁

3.锁最大可以锁整个类(加载类上),最小可以锁一条语句(加在语句上)

4.被synchronized包围住的多个代码块,只要持有的对象锁为同一个,那这些代码块只能同时被单个线程访问

注:在Android开发中,同步锁最好不要加在主线程

注:仅做记录,有错勿喷

Java 超简单控制台多级菜单实现

直接上代码,直接就一个Menus类文件搞定


import java.util.*;

public class Menus {
    public static final boolean DEBUG = false;

    //menu header
    //menu color
    //menu options,priority
    //menu exit,break,continue
    //menu action
//    private static final Map<Integer,Menu> menuMap=new HashMap<>();
//    private static final Map<Integer,MenuOption> optionMap=new HashMap<>();
//    public static Menu obtain(int menuId,Menu parent,MenuOption... options){
//        if(menuMap.containsKey(menuId))return menuMap.get(menuId);
//        menuMap.put(menuId,new Menu(menuId,parent,options));
//        return menuMap.get(menuId);
//    }
//    public static Menu obtain(int menuId,int parentId,MenuOption... options){
//        if(menuMap.containsKey(menuId))return menuMap.get(menuId);
//        menuMap.put(menuId,new Menu(menuId,parentId,options));
//        return menuMap.get(menuId);
//    }
//    public static MenuOption obtain(int id,String title,String summary,MenuAction action,int priority){
//        if(optionMap.containsKey(id))return optionMap.get(id);
//        optionMap.put(id,new MenuOption(id,title,summary,action,priority));
//        return optionMap.get(id);
//    }
//    public static MenuOption obtain(int id,String title,String summary,MenuAction action){
//        return obtain(id,title,summary,action,0);
//    }
    private static final MenuOption menuOptionExit=new MenuOption("exit","",new MenuAction(){
        @Override
        public void doAction() {
            System.exit(0);
        }
    });
    public static class Menu {
        private final List<MenuOption> options = new ArrayList<>();
        private final Menu parentMenu;
        private final Set<String> ids = new HashSet<>();
        private final MenuOption menuOptionBack=new MenuOption("..","",new MenuAction(){
            @Override
            public void doAction() {
                if(Menu.this.parentMenu!=null){
                    Menu.this.parentMenu.show();
                }
            }
        });

        public Menu(Menu parent) {
            this.parentMenu = parent;
        }

        public void addOptions(MenuOption... options) {
            for (MenuOption option : options) {
                if (ids.add(option.name)) {
                    if(option.name.length()>getMaxTitleLength())throw new IllegalArgumentException("Option title max length is "+getMaxTitleLength());
                    this.options.add(option);
                }
            }
        }

        public MenuOption findOptionByName(String name) {
            for (MenuOption option : this.options) {
                if (option.name.equals(name)) {
                    return option;
                }
            }
            return null;
        }
        public List<MenuOption> getAllOption(){
            return new ArrayList<>(this.options);
        }
        public void clearOptions(){
            this.options.clear();
            this.ids.clear();
        }

        public void show() {
            int i = 1;
            Map<Integer, MenuOption> optionMap = new HashMap<>();
            if(this.parentMenu!=null){
                System.out.println(buildOptionText(i,this.menuOptionBack));
                optionMap.put(i++, this.menuOptionBack);
            }
            this.options.sort(Collections.reverseOrder());
            for (MenuOption option : this.options) {
                if (!option.show) continue;
                System.out.println(buildOptionText(i,option));
                optionMap.put(i++, option);
            }
            System.out.println(buildOptionText(i,menuOptionExit));
            optionMap.put(i,menuOptionExit);
            try {
                System.out.print(getInputPrefix());
                Scanner scanner = new Scanner(System.in);
                if (scanner.hasNext()) {
                    int index = scanner.nextInt();
                    if(index>=1&&index<=i){
                        optionMap.get(index).doAction();
                        if(index!=i){
                            show();
                        }
                    }else {
                        System.out.println("warn: please input number 1~"+i);
                        show();
                    }

                }
            } catch (Exception e) {
                if (DEBUG) {
                    e.printStackTrace();
                }
                System.out.println("warn: please input number 1~"+i);
                show();
            }
        }
        protected String buildOptionText(int i,MenuOption option){
            return String.format("%d) %-24s  %s", i, option.name, option.summary);
        }
        protected String getInputPrefix(){
            return "option >";
        }
        protected int getMaxTitleLength(){
            return 20;
        }
    }

    public static class MenuHeader { /*todo*/
    }

    public static class MenuColor { /*todo*/
    }

    public static class MenuOption implements Comparable<MenuOption> {
        private final String name;
        private final String summary;
        private boolean show;
        private MenuAction action;
        private final int priority;

        public MenuOption(String title, String summary, MenuAction action, int priority, boolean show) {
            this.name = title;
            this.summary = summary;
            this.action = action;
            this.priority = priority;
            this.show = show;
        }

        public MenuOption(String title, String summary, MenuAction action, int priority) {
            this(title, summary, action, priority, true);
        }

        public MenuOption(String title, String summary, MenuAction action) {
            this(title, summary, action, 0);
        }

        public void doAction() {
            if (this.action != null) {
                this.action.doAction();
            }
        }

        public MenuOption setShow(boolean isShow) {
            this.show = isShow;
            return this;
        }

        public MenuOption setAction(MenuAction action) {
            this.action = action;
            return this;
        }

        @Override
        public int compareTo(MenuOption o) {
            return this.priority - o.priority;
        }
    }

    public static class MenuAction {
        public void doAction() {
            System.out.println("This is a default action!");
        }
    }

}

简单使用


    private static void printMenu() {
        Menus.Menu rootMenu = new Menus.Menu( null);
        Menus.Menu getPropMenu = new Menus.Menu( rootMenu);
        getPropMenu.addOptions(new Menus.MenuOption( "get adb debug", "get adb debug", new Menus.MenuAction() {
            @Override
            public void doAction() {
                System.out.println("todo get adb debug prop");
            }
        }));
        rootMenu.addOptions(new Menus.MenuOption("sign apk", "sign apk", new Menus.MenuAction() {
                    @Override
                    public void doAction() {
                        System.out.println("todo sign apk");
                    }
                }),
                new Menus.MenuOption("read apk path", "read apk path with adb command", new Menus.MenuAction() {
                    @Override
                    public void doAction() {
                        System.out.println("todo apk path");
                    }
                }),
                new Menus.MenuOption( "check apk", "check apk info", new Menus.MenuAction() {
                    @Override
                    public void doAction() {
                        System.out.println("todo check apk info");
                    }
                })
        );
        rootMenu.addOptions(new Menus.MenuOption( "get prop", "get device prop with adb", new Menus.MenuAction() {
            @Override
            public void doAction() {
                getPropMenu.show();
            }
        }));
        rootMenu.show();
    }

效果演示

​​​​preview

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/862201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AcrelEMS-BP生物制药能效管理系统解决方案

安科瑞 崔丽洁 平台概述 AcrelEMS-BP生物制药能效管理系统集变电站综合自动化、电力监控、电能质量分析及治理、电气安全、能耗分析、照明控制、设备运维于一体。平台采用自动化、信息化技术和集中管理模式&#xff0c;对企业的生产、输配和消耗环节实行集中扁平化的动态监控和…

LTE鉴权失败原因分析

背景介绍&#xff1a;网络发鉴权加密申请后&#xff0c;收到用户响应后&#xff0c;同时又收到reject&#xff0c;reject code 是0x14&#xff0c;还不能确认是否鉴权参数设置问题引起的&#xff0c;欢迎各位专家来讨论及给建议。 reject code如下&#xff1a; 1、通过log&am…

赛码网-回文串 100%AC代码(C)

———————————————————————————————————— ⏩ 大家好哇&#xff01;我是小光&#xff0c;嵌入式爱好者&#xff0c;一个想要成为系统架构师的大三学生。 ⏩最近在准备秋招&#xff0c;一直在练习编程。 ⏩本篇文章对赛码网的回文串 题目做一个…

智慧家庭如何落地?三翼鸟把答案写在用户家里

近年来&#xff0c;学术界流行一句话&#xff0c;“把论文写在中国大地上”。 一项新技术从实验室到千万家&#xff0c;落地难、转化低&#xff0c;是技术创新经常碰到的问题。所以&#xff0c;如何让新技术扎根大地、扎根真实需求&#xff0c;普惠人间&#xff0c;是中国产学研…

Java并发编程第4讲——Java中的锁(知识扫盲)

目录 一、锁的相关概念 1.1 什么是锁 1.2 为什么需要锁 1.3 Java中锁的分类 二、synchronized关键字 2.1 三个特点 2.2 三种表现形式&#xff08;&#x1f64b;‍♂️&#xff09; 2.3 sychronized是怎么实现的&#xff08;&#x1f64b;‍♂️&#xff09; 2.4 JDK1.…

opencv基础52-图像轮廓学习05-凸包获取-cv2.convexHull()

逼近多边形是轮廓的高度近似&#xff0c;但是有时候&#xff0c;我们希望使用一个多边形的凸包来简化它。 凸包跟逼近多边形很像&#xff0c;只不过它是物体最外层的“凸”多边形。凸包指的是完全包含原有轮 廓&#xff0c;并且仅由轮廓上的点所构成的多边形。凸包的每一处都是…

SpringBoot3分库分表

标签&#xff1a;ShardingSphere5.分库.分表&#xff1b; 一、简介 分库分表的设计和实现方式&#xff0c;在之前的内容中总结过很多&#xff0c;本文基于SpringBoot3和ShardingSphere5框架实现数据分库分表的能力&#xff1b; 不得不提ShardingSphere5文档中描述的两个基本概…

伪类和伪元素有何区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 伪类&#xff08;Pseudo-class&#xff09;⭐ 伪元素&#xff08;Pseudo-element&#xff09;⭐ 区别总结⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前…

.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法

前言 前段时间有朋友问道一个这样的问题&#xff0c;.NET Core中如何通过Attribute的元数据信息来调用标记的对应方法。我第一时间想到的就是通过C#反射获取带有Custom Attribute标记的类&#xff0c;然后通过依赖注入&#xff08;DI&#xff09;的方式获取对应服务的方法并通过…

应用在智能仓储温湿度监测系统中的温度传感芯片

近年来各行各业越来越重视产品的仓库、冷库存储环境&#xff0c;食品、药品、化工产品的保存都离不开冷库。温湿度是影响冷库环境的主要因素&#xff0c;建立实时的温湿度监控系统&#xff0c;保存查看完整的历史温湿度数据十分必要。 物资的保存对存储环境的质量要求较为严格…

Spring IoC 详解

目录 一、引言二、Spring Bean三、将一个类声明为 Bean 所涉及的注解四、Component 和 Bean 的区别五、注入 Bean 的注解六、Autowired 和 Resource 的区别七、Bean7.1 作用域7.2 线程安全7.3 生命周期 一、引言 IoC&#xff08;Inversion of Control:控制反转&#xff09; 是…

JUC线程池的实战问题引出的一系列原理问题

1 我们为什么需要使用线程池 线程过多会带来额外的开销&#xff0c;其中包括创建销毁线程的开销、调度线程的开销等等&#xff0c;同时也降低了计算机的整体性能。线程池维护多个线程&#xff0c;等待、监督、管理、分配可并发执行的任务。这种做法&#xff0c;一方面避免了处…

分享3款屏幕录制软件,一定要来看!

在数字化时代&#xff0c;屏幕录制软件成为了一个必不可少的工具。它可以帮助用户捕捉并记录计算机屏幕上的活动&#xff0c;因此选择一款功能强大、易于使用的屏幕录制软件至关重要。本文将介绍3款备受好评的屏幕录制软件&#xff0c;通过本文的阅读&#xff0c;您将了解到它们…

Android图形-刷新与显示

目录 屏幕显示原理&#xff1a; 显示刷新的过程 VSYNC机制具体实现 小结&#xff1a; 屏幕显示原理&#xff1a; 过程描述&#xff1a; 应用向系统服务申请buffer 系统服务返回一个buffer给应用 应用开始绘制&#xff0c;绘制完成就提交buffer&#xff0c;系统服务把buffer数据…

两年了^

我也想不到是到了现在 记得刚来腾讯工作半年时候&#xff0c;我写了一篇文章 在腾讯的这半年 之后&#xff0c;又经过了半年时间&#xff0c;我又写了一篇总结文章 一年了 现在又过了一年多&#xff0c;本想把两年的入职截图留下&#xff0c;之前因为微信存储太大把微信卸载后重…

实现功能:ChatGPT 微信助手可以自动搜索网络信息回答问题

“ ChatGPT微信助手升级内测功能上线&#xff01;原先只能回答通用问题,现在遇到需要查询具体信息的问题也不愁啦。” 01 — 最近&#xff0c;上线了ChatGPT微信助手的体验群&#xff1a;《ChatGPT 微信助手上线&#xff01;问答更便捷&#xff0c;功能持续升级中。》&#xff…

Android高手进阶教程(一)-------Android常用名令集锦(图文并茂)!

大家好&#xff0c;今天我们要讲的是android开发中&#xff0c;比较常用的名令集锦&#xff0c; 在我们开发中难免用到Android命令&#xff0c;有些确实命令确实很有用处。 特别对于一些初学者来说&#xff0c;命令根本没有想过用也不会用&#xff0c;比如他们想安装一个.apk文…

以太网网络安全协议(十三)

一、IPsec协议 IPsec。它是指在IP首部的后面追加“封装安全有效载荷”&#xff08;ESP&#xff09;和“认证首部”&#xff08;AH&#xff09; &#xff0c;从而对此后的数据进行加密&#xff0c;不被盗取者轻易解读。 二、TLS/SLL协议 SSL最早由网景公司提出&#xff0c;标准化…

架构设计第42讲:美团 - 可视化全链路日志追踪

架构设计第42讲&#xff1a;美团 - 可视化全链路日志追踪 目前在分布式场景下&#xff0c;业务追踪的主流实现方式包括两类&#xff0c;一类是基于日志的ELK方案&#xff0c;一类是基于单次请求调用的会话跟踪方案。然而随着业务逻辑的日益复杂&#xff0c;上述方案越来越不适用…

8月10日,每日信息差

1、菜鸟国际快递“承诺达、晚必赔”覆盖22国。具体来讲&#xff0c;菜鸟国际快递对无忧、经济和简易三种标准产品全面升级&#xff0c;其中英国、意大利、加拿大、美国四国时效平均提升30%以上。凡使用这三种快递产品发货至22国的商家&#xff0c;其货物在速卖通电商平台享有“…