那些年的Java开发经验记录

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(){@Overridepublic 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(){@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void doAction() {System.out.println("todo get adb debug prop");}}));rootMenu.addOptions(new Menus.MenuOption("sign apk", "sign apk", new Menus.MenuAction() {@Overridepublic void doAction() {System.out.println("todo sign apk");}}),new Menus.MenuOption("read apk path", "read apk path with adb command", new Menus.MenuAction() {@Overridepublic void doAction() {System.out.println("todo apk path");}}),new Menus.MenuOption( "check apk", "check apk info", new Menus.MenuAction() {@Overridepublic void doAction() {System.out.println("todo check apk info");}}));rootMenu.addOptions(new Menus.MenuOption( "get prop", "get device prop with adb", new Menus.MenuAction() {@Overridepublic void doAction() {getPropMenu.show();}}));rootMenu.show();}

效果演示

​​​​preview

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【框架类】—Vue3的生命周期

一、生命周期的相关函数 onBeforeMount 页面渲染之前 和 onMounted渲染之后 示例 <template><div class"test"><div ref"el">组件初始化</div></div> </template> <script> //按需引入所需方法 import { ref,…

Redux - Redux在React函数式组件中的基本使用

文章目录 一&#xff0c;简介二&#xff0c;安装三&#xff0c;三大核心概念Store、Action、Reducer3.1 Store3.2 Reducer3.3 Action 四&#xff0c;开始函数式组件中使用4.1&#xff0c;引入store4.1&#xff0c;store.getState()方法4.3&#xff0c;store.dispatch()方法4.4&…

04-4_Qt 5.9 C++开发指南_时间日期与定时器

文章目录 1. 时间日期相关的类2. 源码2.1 可视化UI设计2.2 dialog.h2.3 dialog.cpp 1. 时间日期相关的类 时间日期是经常遇到的数据类型&#xff0c;Qt 中时间日期类型的类如下。 QTime:时间数据类型&#xff0c;仅表示时间&#xff0c;如 15:23:13。 QDate:日期数据类型&…

虹科方案 | 汽车总线协议转换解决方案

汽车总线&#xff1a; 汽车总线是一种用于在车辆电子系统中传输数据和控制信息的通信系统。它允许不同的电子控制单元&#xff08;ECU&#xff09;在车辆中相互通信&#xff0c;协调各个系统的操作&#xff0c;以实现功能的集成和协同工作。 在现代汽车中&#xff0c;综合通信…

微信公众号模板消息推送测试Python版无需服务器-保姆级教程

手上有个项目&#xff0c;是服务器挂着自动化的爬虫的&#xff0c;但我用的那个IP代理商没有用尽报警&#xff0c;导致几次IP用尽&#xff0c;程序爬不到数据&#xff0c;进程死循环了。之前想过发邮箱提醒我&#xff0c;但是邮箱把又不及时&#xff0c;老忘记看&#xff0c;因…

C语言必会题目(1)

W...Y的主页 &#x1f60a; 代码仓库分享❤️ 在学习语言时&#xff0c;最重要的就是练习&#xff0c;光听不练假把式。下面我就推荐一些C语言必会的题。 执行下面程序&#xff0c;正确的输出是&#xff08; &#xff09; int x5,y7; void swap() { int z; zx; xy; yz; } int…

数字孪生三剑客来了!MapGIS Earth for Unreal的自述

嗨&#xff0c;大家好&#xff01;我的名字叫MapGIS Earth for Unreal&#xff0c;是MapGIS数字孪生平台产品家族的一员。提起我&#xff0c;大家可能不熟悉&#xff0c;但是提起数字孪生&#xff0c;想必大家倍感兴趣。 数字孪生是充分利用物理模型、传感器更新、运行历史等数…

【git】解决遇到的问题

目录 一、error: RPC failed; curl 6 OpenSSL SSL_read: Connection was reset, errno 10054 二、error: RPC failed; curl 6 OpenSSL SSL_read: Connection was reset, errno 10054 一、error: RPC failed; curl 6 OpenSSL SSL_read: Connection was reset, errno 10054 报…

2023最新Windows编译ffmpeg详细教程,附msys2详细安装配置教程

安装MSYS2 msys2是一款跨平台编译套件&#xff0c;它模拟linux编译环境&#xff0c;支持整合mingw32和mingw64&#xff0c;能很方便的在windows上对一些开源的linux工程进行编译运行。 类似的跨平台编译套件有&#xff1a;msys&#xff0c;cygwin&#xff0c;mingw 优势&…

MySQL8的特性-MySQL8知识详解

MySQL是一个多用户、多线程的SQL数据库服务器。SQL&#xff08;结构化查询语言&#xff09;是世界上最流行和标准化的数据库语言。下面是MySQL的特性。 1、开源性&#xff1a;MySQL是一个开源的关系型数据库管理系统&#xff0c;可以免费使用和修改。 2、可靠性&#xff1a;M…

DOCKER的容器

1. 什么是Container&#xff08;容器&#xff09; 要有Container首先要有Image&#xff0c;也就是说Container是通过image创建的。 Container是在原先的Image之上新加的一层&#xff0c;称作Container layer&#xff0c;这一层是可读可写的&#xff08;Image是只读的&#xff0…

TOMCAT部署及优化(Tomcat配置文件参数优化,Java虚拟机(JVM)调优)

TOMCAT tomcat &#xff1a;是一个开放源代码的web应用服务器&#xff0c;基于java代码开发的。也可以理解为tomacat就是处理动态请求和基于java代码的页面开发。可以在html当中写入java代码&#xff0c;tomcat可以解析html页面当中的java&#xff0c;执行动态请求&#xff0c;…

Nvm安装与使用

【1】nvm下载地址 https://github.com/coreybutler/nvm-windows/releases 选择的是nvm-setup.exe 【2】安装nvm 打开cmd&#xff0c;输入命令nvm -v 查看nvm版本&#xff0c;出现如下界面说明成功 【3】nodejs 安装与管理 打开CMD命令&#xff0c;以管理员权限运行 1、…

如何维护自己的电脑

目录 1、关于电脑选择的建议 1.1、价格预算 1.2、明确需求 1.3、电脑配置 1.4、分辨率 1.5、续航能力 1.6、品牌选择 1.7、用户评测 1.8、各个电商平台对比 1.9、最后决策 2、我的选择 3、电脑保养 3.1 外部清洁 3.2 安装软件 3.3 优化操作系统 3.4 维护硬件设…

那些年的golang开发经验记录

goland 问题CreateProcess error216, 该版本的 %1 与你运行的 Windows 版本不兼容。请查看计算机的系统信息&#xff0c;然后联系软件发布者 Cannot run program "......" (in directory "D:\project\go\awesomeProject\src\test"): CreateProcess error2…

Linux系列:从0到1用Docker部署springboot项目

目录 1.前提条件 2.编写DockerFile镜像文件 3.打包SpringBoot项目 4.通过软件Xftp进行传输&#xff08;*&#xff09; 1.点击“文件-新建”​编辑 5.操作远程主机 1.docker构建 2.容器运行 6.容器的关闭和删除 1.前提条件 Linux、docker、xftp的安装、一台可以访问的远…

GIL 锁或将在 CPython 中成为可选项

哈喽大家好&#xff0c;我是咸鱼 几天前有媒体报道称&#xff0c;经过多次辩论&#xff0c;Python 指导委员会打算批准通过 PEP 703 提案&#xff0c;让 GIL&#xff08;全局解释器&#xff09;锁在 CPython 中成为一个可选项 PEP 703 提案主要目标是使 GIL 变成可选项&#…

flink如何监听kafka主题配置变更

背景&#xff1a; 从前一篇文章我们知道flink消费kafka主题时是采用的手动assign指定分区的方式&#xff0c;这种消费方式是不处理主题的rebalance操作的&#xff0c;也就是消费者组中即使有消费者退出或者进入也是不会触发消费者所消费的分区的&#xff0c;那么疑问就来了&am…

【CSS】背景图定位问题适配不同机型

需求 如图, 实现一个带有飘带的渐变背景 其中头像必须显示飘带凹下去那里 , 需要适配不同的机型, 一不下心容易错位 实现 因为飘带背景是版本迭代中更新的, 所以飘带和渐变背景实则两个div 飘带切图如下 , 圆形部分需要契合头像 <view class"box-bg"><…