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();}
效果演示