[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*.{groovy, java, kt, xml}]\n#缩进风格：空格\nindent_style = space\n#缩进大小\nindent_size = 4\n#换行符lf\nend_of_line = lf\n#字符集utf-8\ncharset = utf-8\n#是否删除行尾的空格\ntrim_trailing_whitespace = true\n#是否在文件的最后插入一个空行\ninsert_final_newline = true"
  },
  {
    "path": ".gitignore",
    "content": "# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.nar\n*.ear\n*.zip\n*.tar.gz\n*.rar\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n# Eclipse project files\n.classpath\n.project\n.settings\n.settings/\ntarget/\n\n# IDEA metadata and output dirs\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# gitbook\n_book\ntmp\n.springBeans"
  },
  {
    "path": ".mvn/jvm.config",
    "content": "-Xmx1536m"
  },
  {
    "path": ".mvn/wrapper/maven-wrapper.properties",
    "content": "distributionUrl=https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.zip\nwrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar"
  },
  {
    "path": ".travis.yml",
    "content": "language: java\njdk: openjdk8\ncache:\n  directories:\n    - $HOME/.m2\nbefore_install:\n  - chmod +x mvnw\ninstall:\n  - ./mvnw install -B -V -Dmaven.test.skip=true"
  },
  {
    "path": "README.md",
    "content": "### 小统计：\n\n![Stargazers over time](https://starchart.cc/MarkShen1992/Mashibing_High_Concurrency.svg)\n\n> **Don't count the days, make each day count.**\n\n### 代码目录\n\n- Chapter00_初识Java\n  - Hello World\n  - 初步认识\n  - 代码风格\n    - [谷歌代码风格](https://google.github.io/styleguide)\n    - [阿里代码风格](https://github.com/alibaba/p3c)\n\n- [Chapter01_Java语言基础](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0100)\n  - **关键字**：if, else, switch, for, while, do while, break, continue, void\n  \n  - 变量作用域：**出了这个大括号就再也没有人认识这个变量了。**\n  \n  - 基本数据类型：**四类八种**\n    - 整数类型：byte(1 byte), short(2 bytes), int(4 bytes), long(8 bytes)\n    - 浮点类型：float(4 bytes), double(8 bytes)\n    - 字符类型：char(2 bytes)\n    - 布尔类型：boolean\n  \n    > Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machine **int** data type.\n    >\n    > ​                                                                                                                                                   -- [*JVMS8*](https://github.com/MarkShen1992/bookstore/tree/master/java/Java%20Virtual%20Machine/jvm8)\n    \n    ```java\n    boolean flag = false;\n    ```\n    \n    >In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per boolean element.\n    >\n    >​                                                                                                                                                   -- [*JVMS8*](https://github.com/MarkShen1992/bookstore/tree/master/java/Java%20Virtual%20Machine/jvm8)\n    \n    ```java\n    boolean[] flags = {false, true, false, true, true};\n    ```\n  \n  - 形参，实参，返回值，返回值类型\n  - 递归调用\n  \n- [**Chapter02_面向对象编程**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0200)\n  \n  - **内存分析贯穿始终，画图分析**\n  - 对象与类的概念\n  - **面向对象设计思想**\n    - 第一步：考虑问题域中有哪些类，哪些对象\n    - 第二步：这些个类，这些个对象有哪些个属性\n    - 第三步：考虑类与类之间的关系，定他们之间的方法\n  - class\n  - new\n    - 引用的概念\n    - 构造方法的概念\n  - 方法重载(编译时多态)\n    - 参数个数\n    - 参数类型\n    - 参数顺序\n  - this\n  - super\n  - static\n  - package & import\n  - private default protected public\n  - extends\n  - override\n  - final\n  - Object\n    - equals\n    - toString\n  - upcasting downcasting\n  - polymorphism  / dynamic binding / late\n    - 有继承关系存在\n    - 存在方法重写 @Override\n    - 父类引用指向子类对象\n  \n- abstract class\n  - interface\n    - implements\n  \n- [Chapter03_Java异常处理机制](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0300)\n  - 一个图\n  \n  ![Exception](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/materials/Exception.png)\n  - 五个关键字\n    - try, catch, finally, throw, throws\n  - 异常捕获原则\n    - 先逮小的，再逮大的\n    - 异常和重写的关系: **重写方法需要抛出与原方法所抛出异常类型一致的异常 或者 不抛出异常**\n  \n- [Chapter04_数组](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0400)\n  - 数组的内存布局\n  - 常见算法\n\n- [Chapter05_Java常用类](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0500)\n  - 正则表达式\n  - 基础类型包装类\n  - Math\n  - File\n    - 递归\n  - 枚举类型\n\n- [**Chapter06_容器类**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0600)\n  - 一个图\n  \n  ![Collection Framework](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/materials/CollectionFramework.png)\n  - 一个类\n    - Collections\n  - 三个知识点\n    - For\n    - Generic\n    - Auto-boxing / unboxing\n  - 六个接口\n    - Collection\n    - Set\n    - List\n    - Map\n    - Iterator\n    - Comparable\n\n- [**Chapter07_IO流技术**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0700)\n  \n  ![Java IO](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/materials/Java%20IO.jpg)\n  \n  - InputStream / OutputStream\n  - Reader / Writer\n  - FileInputStream / FileOutputStream\n  - FileReader / FileWriter\n  - BufferedInputStream / BufferedOutputStream\n  - BufferedReader / BufferedWriter\n  - ByteArrayInputStream / ByteArrayOutputStream\n  - InputStreamReader / OutputStreamWriter\n  - DataInputStream / DataOutputStream\n  - PrintStream / PrintWriter\n  - ObjectInputStream / ObjectOutputStream\n  - 分类\n    - 方向：输入流，输出流\n    - 数据处理单位：字节流，字符流\n    - 功能：节点流，处理流\n  \n- [**Chapter08_多线程**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0800)\n  - 线程/进程/协程\n  - 创建启动线程的方式\n  - sleep, join, yield, synchronized, wait, notify, notifyAll\n\n- [Chapter09_网络编程](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0900)\n  - 网络协议分层思想\n  - IP概念\n  - TCP / UDP概念\n  - TCP / UDP程序的写法\n    - 知识点融会贯通，+ io 应用\n\n- [Chapter10_GUI](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter1000)\n  - 事件模型，**观察者模式**\n  - [设计模式的代码](https://github.com/MarkShen1992/DesignPattern), 使用MyEclipse打开更好，有图可以看\n\n- [Chapter11_反射](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter1100)\n\n- [**Chapter12_并发包类讲解代码**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/mark)\n\n  - [第一讲 concurrent1-19](https://v.qq.com/x/page/x052229kmeq.html)\n\n  - [第二讲 concurrent20-22](https://v.qq.com/x/page/f05224z6ul9.html)\n\n  - [第三讲 concurrent23-25](https://v.qq.com/x/page/z0522fzc1q3.html)\n\n  - [第四讲 concurrent26](https://v.qq.com/x/page/u0522rgqjyk.html)\n\n  - 高并发编程三大块：\n    - 同步器(synchronizer)\n    - 同步容器\n    - 线程池\n    - Executor\n    - Future\n    - Callable\n\n  - 框架\n    - [disruptor](https://github.com/LMAX-Exchange/disruptor)\n    - [netty](https://netty.io/)\n\n- [Chapter13_利用反射做的小项目](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/annotation)\n\n- 常用工具代码\n\n  - [树形结构遍历](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/src/main/java/com/program/ConstructTree.java)\n  - [Code生成](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/src/main/java/com/program/CodeGenerator.java)\n\n如果你喜欢这个项目，请我喝杯咖啡吧。\n\n<img src=\"./like.jpg\" alt=\"drawing\" width=\"300\" style=\"float: left;\"/>\n\n\n\n\n\n\n"
  },
  {
    "path": "concurrency.md",
    "content": "# 马士兵高并发编程视频教程源码。\n\n### 线程池类图\n\n![线程池类图2](http://www.ideabuffer.cn/2017/04/04/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E7%BA%BF%E7%A8%8B%E6%B1%A0%EF%BC%9AThreadPoolExecutor/QQ20170331-004227.png)\n\n\n\n### 计算机体系结构\n\n![冯诺依曼](http://images2015.cnblogs.com/blog/407610/201510/407610-20151014095555022-881385577.jpg)\n\n\n\n![冯诺依曼体系结构](https://yun.kejimofang.com/intericon/20190427nuoyi.jpg)\n\n\n\n![冯诺依曼](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61604.png)\n\n\n\n![CPU&RAM](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61606.png)\n\n\n\n![CPU&RAM](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61610.png)\n\n\n\n![CPU&RAM](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61612.png)\n\n\n\n![computer](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61622.png)\n\n计算机硬件知识\n\n<https://www.phy.ornl.gov/csep/ca/ca.html>"
  },
  {
    "path": "jvm/jvm8 all parameters.txt",
    "content": "java -XX:+PrintFlagsFinal -version\n\njava version \"1.8.0_112\"\nJava(TM) SE Runtime Environment (build 1.8.0_112-b15)\nJava HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)\n\nJVM 参数学习网站\nhttps://segmentfault.com/a/1190000040803727\nhttps://opts.console.heapdump.cn/\n\n[Global flags]\n    uintx AdaptiveSizeDecrementScaleFactor          = 4                                   {product}\n    uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}\n    uintx AdaptiveSizePausePolicy                   = 0                                   {product}\n    uintx AdaptiveSizePolicyCollectionCostMargin    = 50                                  {product}\n    uintx AdaptiveSizePolicyInitializingSteps       = 20                                  {product}\n    uintx AdaptiveSizePolicyOutputInterval          = 0                                   {product}\n    uintx AdaptiveSizePolicyWeight                  = 10                                  {product}\n    uintx AdaptiveSizeThroughPutPolicy              = 0                                   {product}\n    uintx AdaptiveTimeWeight                        = 25                                  {product}\n     bool AdjustConcurrency                         = false                               {product}\n     bool AggressiveOpts                            = false                               {product}\n     intx AliasLevel                                = 3                                   {C2 product}\n     bool AlignVector                               = true                                {C2 product}\n     intx AllocateInstancePrefetchLines             = 1                                   {product}\n     intx AllocatePrefetchDistance                  = 256                                 {product}\n     intx AllocatePrefetchInstr                     = 0                                   {product}\n     intx AllocatePrefetchLines                     = 3                                   {product}\n     intx AllocatePrefetchStepSize                  = 64                                  {product}\n     intx AllocatePrefetchStyle                     = 1                                   {product}\n     bool AllowJNIEnvProxy                          = false                               {product}\n     bool AllowNonVirtualCalls                      = false                               {product}\n     bool AllowParallelDefineClass                  = false                               {product}\n     bool AllowUserSignalHandlers                   = false                               {product}\n     bool AlwaysActAsServerClassMachine             = false                               {product}\n     bool AlwaysCompileLoopMethods                  = false                               {product}\n     bool AlwaysLockClassLoader                     = false                               {product}\n     bool AlwaysPreTouch                            = false                               {product}\n     bool AlwaysRestoreFPU                          = false                               {product}\n     bool AlwaysTenure                              = false                               {product}\n     bool AssertOnSuspendWaitFailure                = false                               {product}\n     bool AssumeMP                                  = false                               {product}\n     intx AutoBoxCacheMax                           = 128                                 {C2 product}\n    uintx AutoGCSelectPauseMillis                   = 5000                                {product}\n     intx BCEATraceLevel                            = 0                                   {product}\n     intx BackEdgeThreshold                         = 100000                              {pd product}\n     bool BackgroundCompilation                     = true                                {pd product}\n    uintx BaseFootPrintEstimate                     = 268435456                           {product}\n     intx BiasedLockingBulkRebiasThreshold          = 20                                  {product}\n     intx BiasedLockingBulkRevokeThreshold          = 40                                  {product}\n     intx BiasedLockingDecayTime                    = 25000                               {product}\n     intx BiasedLockingStartupDelay                 = 4000                                {product}\n     bool BindGCTaskThreadsToCPUs                   = false                               {product}\n     bool BlockLayoutByFrequency                    = true                                {C2 product}\n     intx BlockLayoutMinDiamondPercentage           = 20                                  {C2 product}\n     bool BlockLayoutRotateLoops                    = true                                {C2 product}\n     bool BranchOnRegister                          = false                               {C2 product}\n     bool BytecodeVerificationLocal                 = false                               {product}\n     bool BytecodeVerificationRemote                = true                                {product}\n     bool C1OptimizeVirtualCallProfiling            = true                                {C1 product}\n     bool C1ProfileBranches                         = true                                {C1 product}\n     bool C1ProfileCalls                            = true                                {C1 product}\n     bool C1ProfileCheckcasts                       = true                                {C1 product}\n     bool C1ProfileInlinedCalls                     = true                                {C1 product}\n     bool C1ProfileVirtualCalls                     = true                                {C1 product}\n     bool C1UpdateMethodData                        = true                                {C1 product}\n     intx CICompilerCount                          := 4                                   {product}\n     bool CICompilerCountPerCPU                     = true                                {product}\n     bool CITime                                    = false                               {product}\n     bool CMSAbortSemantics                         = false                               {product}\n    uintx CMSAbortablePrecleanMinWorkPerIteration   = 100                                 {product}\n     intx CMSAbortablePrecleanWaitMillis            = 100                                 {manageable}\n    uintx CMSBitMapYieldQuantum                     = 10485760                            {product}\n    uintx CMSBootstrapOccupancy                     = 50                                  {product}\n     bool CMSClassUnloadingEnabled                  = true                                {product}\n    uintx CMSClassUnloadingMaxInterval              = 0                                   {product}\n     bool CMSCleanOnEnter                           = true                                {product}\n     bool CMSCompactWhenClearAllSoftRefs            = true                                {product}\n    uintx CMSConcMarkMultiple                       = 32                                  {product}\n     bool CMSConcurrentMTEnabled                    = true                                {product}\n    uintx CMSCoordinatorYieldSleepCount             = 10                                  {product}\n     bool CMSDumpAtPromotionFailure                 = false                               {product}\n     bool CMSEdenChunksRecordAlways                 = true                                {product}\n    uintx CMSExpAvgFactor                           = 50                                  {product}\n     bool CMSExtrapolateSweep                       = false                               {product}\n    uintx CMSFullGCsBeforeCompaction                = 0                                   {product}\n    uintx CMSIncrementalDutyCycle                   = 10                                  {product}\n    uintx CMSIncrementalDutyCycleMin                = 0                                   {product}\n     bool CMSIncrementalMode                        = false                               {product}\n    uintx CMSIncrementalOffset                      = 0                                   {product}\n     bool CMSIncrementalPacing                      = true                                {product}\n    uintx CMSIncrementalSafetyFactor                = 10                                  {product}\n    uintx CMSIndexedFreeListReplenish               = 4                                   {product}\n     intx CMSInitiatingOccupancyFraction            = -1                                  {product}\n    uintx CMSIsTooFullPercentage                    = 98                                  {product}\n   double CMSLargeCoalSurplusPercent                = 0.950000                            {product}\n   double CMSLargeSplitSurplusPercent               = 1.000000                            {product}\n     bool CMSLoopWarn                               = false                               {product}\n    uintx CMSMaxAbortablePrecleanLoops              = 0                                   {product}\n     intx CMSMaxAbortablePrecleanTime               = 5000                                {product}\n    uintx CMSOldPLABMax                             = 1024                                {product}\n    uintx CMSOldPLABMin                             = 16                                  {product}\n    uintx CMSOldPLABNumRefills                      = 4                                   {product}\n    uintx CMSOldPLABReactivityFactor                = 2                                   {product}\n     bool CMSOldPLABResizeQuicker                   = false                               {product}\n    uintx CMSOldPLABToleranceFactor                 = 4                                   {product}\n     bool CMSPLABRecordAlways                       = true                                {product}\n    uintx CMSParPromoteBlocksToClaim                = 16                                  {product}\n     bool CMSParallelInitialMarkEnabled             = true                                {product}\n     bool CMSParallelRemarkEnabled                  = true                                {product}\n     bool CMSParallelSurvivorRemarkEnabled          = true                                {product}\n    uintx CMSPrecleanDenominator                    = 3                                   {product}\n    uintx CMSPrecleanIter                           = 3                                   {product}\n    uintx CMSPrecleanNumerator                      = 2                                   {product}\n     bool CMSPrecleanRefLists1                      = true                                {product}\n     bool CMSPrecleanRefLists2                      = false                               {product}\n     bool CMSPrecleanSurvivors1                     = false                               {product}\n     bool CMSPrecleanSurvivors2                     = true                                {product}\n    uintx CMSPrecleanThreshold                      = 1000                                {product}\n     bool CMSPrecleaningEnabled                     = true                                {product}\n     bool CMSPrintChunksInDump                      = false                               {product}\n     bool CMSPrintEdenSurvivorChunks                = false                               {product}\n     bool CMSPrintObjectsInDump                     = false                               {product}\n    uintx CMSRemarkVerifyVariant                    = 1                                   {product}\n     bool CMSReplenishIntermediate                  = true                                {product}\n    uintx CMSRescanMultiple                         = 32                                  {product}\n    uintx CMSSamplingGrain                          = 16384                               {product}\n     bool CMSScavengeBeforeRemark                   = false                               {product}\n    uintx CMSScheduleRemarkEdenPenetration          = 50                                  {product}\n    uintx CMSScheduleRemarkEdenSizeThreshold        = 2097152                             {product}\n    uintx CMSScheduleRemarkSamplingRatio            = 5                                   {product}\n   double CMSSmallCoalSurplusPercent                = 1.050000                            {product}\n   double CMSSmallSplitSurplusPercent               = 1.100000                            {product}\n     bool CMSSplitIndexedFreeListBlocks             = true                                {product}\n     intx CMSTriggerInterval                        = -1                                  {manageable}\n    uintx CMSTriggerRatio                           = 80                                  {product}\n     intx CMSWaitDuration                           = 2000                                {manageable}\n    uintx CMSWorkQueueDrainThreshold                = 10                                  {product}\n     bool CMSYield                                  = true                                {product}\n    uintx CMSYieldSleepCount                        = 0                                   {product}\n    uintx CMSYoungGenPerWorker                      = 67108864                            {pd product}\n    uintx CMS_FLSPadding                            = 1                                   {product}\n    uintx CMS_FLSWeight                             = 75                                  {product}\n    uintx CMS_SweepPadding                          = 1                                   {product}\n    uintx CMS_SweepTimerThresholdMillis             = 10                                  {product}\n    uintx CMS_SweepWeight                           = 75                                  {product}\n     bool CheckEndorsedAndExtDirs                   = false                               {product}\n     bool CheckJNICalls                             = false                               {product}\n     bool ClassUnloading                            = true                                {product}\n     bool ClassUnloadingWithConcurrentMark          = true                                {product}\n     intx ClearFPUAtPark                            = 0                                   {product}\n     bool ClipInlining                              = true                                {product}\n    uintx CodeCacheExpansionSize                    = 65536                               {pd product}\n    uintx CodeCacheMinimumFreeSpace                 = 512000                              {product}\n     bool CollectGen0First                          = false                               {product}\n     bool CompactFields                             = true                                {product}\n     intx CompilationPolicyChoice                   = 3                                   {product}\nccstrlist CompileCommand                            =                                     {product}\n    ccstr CompileCommandFile                        =                                     {product}\nccstrlist CompileOnly                               =                                     {product}\n     intx CompileThreshold                          = 10000                               {pd product}\n     bool CompilerThreadHintNoPreempt               = true                                {product}\n     intx CompilerThreadPriority                    = -1                                  {product}\n     intx CompilerThreadStackSize                   = 0                                   {pd product}\n    uintx CompressedClassSpaceSize                  = 1073741824                          {product}\n    uintx ConcGCThreads                             = 0                                   {product}\n     intx ConditionalMoveLimit                      = 3                                   {C2 pd product}\n     intx ContendedPaddingWidth                     = 128                                 {product}\n     bool ConvertSleepToYield                       = true                                {pd product}\n     bool ConvertYieldToSleep                       = false                               {product}\n     bool CrashOnOutOfMemoryError                   = false                               {product}\n     bool CreateMinidumpOnCrash                     = false                               {product}\n     bool CriticalJNINatives                        = true                                {product}\n     bool DTraceAllocProbes                         = false                               {product}\n     bool DTraceMethodProbes                        = false                               {product}\n     bool DTraceMonitorProbes                       = false                               {product}\n     bool Debugging                                 = false                               {product}\n    uintx DefaultMaxRAMFraction                     = 4                                   {product}\n     intx DefaultThreadPriority                     = -1                                  {product}\n     intx DeferPollingPageLoopCount                 = -1                                  {product}\n     intx DeferThrSuspendLoopCount                  = 4000                                {product}\n     bool DeoptimizeRandom                          = false                               {product}\n     bool DisableAttachMechanism                    = false                               {product}\n     bool DisableExplicitGC                         = false                               {product}\n     bool DisplayVMOutputToStderr                   = false                               {product}\n     bool DisplayVMOutputToStdout                   = false                               {product}\n     bool DoEscapeAnalysis                          = true                                {C2 product}\n     bool DontCompileHugeMethods                    = true                                {product}\n     bool DontYieldALot                             = false                               {pd product}\n    ccstr DumpLoadedClassList                       =                                     {product}\n     bool DumpReplayDataOnError                     = true                                {product}\n     bool DumpSharedSpaces                          = false                               {product}\n     bool EagerXrunInit                             = false                               {product}\n     intx EliminateAllocationArraySizeLimit         = 64                                  {C2 product}\n     bool EliminateAllocations                      = true                                {C2 product}\n     bool EliminateAutoBox                          = true                                {C2 product}\n     bool EliminateLocks                            = true                                {C2 product}\n     bool EliminateNestedLocks                      = true                                {C2 product}\n     intx EmitSync                                  = 0                                   {product}\n     bool EnableContended                           = true                                {product}\n     bool EnableResourceManagementTLABCache         = true                                {product}\n     bool EnableSharedLookupCache                   = true                                {product}\n     bool EnableTracing                             = false                               {product}\n    uintx ErgoHeapSizeLimit                         = 0                                   {product}\n    ccstr ErrorFile                                 =                                     {product}\n    ccstr ErrorReportServer                         =                                     {product}\n   double EscapeAnalysisTimeout                     = 20.000000                           {C2 product}\n     bool EstimateArgEscape                         = true                                {product}\n     bool ExitOnOutOfMemoryError                    = false                               {product}\n     bool ExplicitGCInvokesConcurrent               = false                               {product}\n     bool ExplicitGCInvokesConcurrentAndUnloadsClasses  = false                               {product}\n     bool ExtendedDTraceProbes                      = false                               {product}\n    ccstr ExtraSharedClassListFile                  =                                     {product}\n     bool FLSAlwaysCoalesceLarge                    = false                               {product}\n    uintx FLSCoalescePolicy                         = 2                                   {product}\n   double FLSLargestBlockCoalesceProximity          = 0.990000                            {product}\n     bool FailOverToOldVerifier                     = true                                {product}\n     bool FastTLABRefill                            = true                                {product}\n     intx FenceInstruction                          = 0                                   {ARCH product}\n     intx FieldsAllocationStyle                     = 1                                   {product}\n     bool FilterSpuriousWakeups                     = true                                {product}\n    ccstr FlightRecorderOptions                     =                                     {product}\n     bool ForceNUMA                                 = false                               {product}\n     bool ForceTimeHighResolution                   = false                               {product}\n     intx FreqInlineSize                            = 325                                 {pd product}\n   double G1ConcMarkStepDurationMillis              = 10.000000                           {product}\n    uintx G1ConcRSHotCardLimit                      = 4                                   {product}\n    uintx G1ConcRSLogCacheSize                      = 10                                  {product}\n     intx G1ConcRefinementGreenZone                 = 0                                   {product}\n     intx G1ConcRefinementRedZone                   = 0                                   {product}\n     intx G1ConcRefinementServiceIntervalMillis     = 300                                 {product}\n    uintx G1ConcRefinementThreads                   = 0                                   {product}\n     intx G1ConcRefinementThresholdStep             = 0                                   {product}\n     intx G1ConcRefinementYellowZone                = 0                                   {product}\n    uintx G1ConfidencePercent                       = 50                                  {product}\n    uintx G1HeapRegionSize                          = 0                                   {product}\n    uintx G1HeapWastePercent                        = 5                                   {product}\n    uintx G1MixedGCCountTarget                      = 8                                   {product}\n     intx G1RSetRegionEntries                       = 0                                   {product}\n    uintx G1RSetScanBlockSize                       = 64                                  {product}\n     intx G1RSetSparseRegionEntries                 = 0                                   {product}\n     intx G1RSetUpdatingPauseTimePercent            = 10                                  {product}\n     intx G1RefProcDrainInterval                    = 10                                  {product}\n    uintx G1ReservePercent                          = 10                                  {product}\n    uintx G1SATBBufferEnqueueingThresholdPercent    = 60                                  {product}\n     intx G1SATBBufferSize                          = 1024                                {product}\n     intx G1UpdateBufferSize                        = 256                                 {product}\n     bool G1UseAdaptiveConcRefinement               = true                                {product}\n    uintx GCDrainStackTargetSize                    = 64                                  {product}\n    uintx GCHeapFreeLimit                           = 2                                   {product}\n    uintx GCLockerEdenExpansionPercent              = 5                                   {product}\n     bool GCLockerInvokesConcurrent                 = false                               {product}\n    uintx GCLogFileSize                             = 8192                                {product}\n    uintx GCPauseIntervalMillis                     = 0                                   {product}\n    uintx GCTaskTimeStampEntries                    = 200                                 {product}\n    uintx GCTimeLimit                               = 98                                  {product}\n    uintx GCTimeRatio                               = 99                                  {product}\n    uintx HeapBaseMinAddress                        = 2147483648                          {pd product}\n     bool HeapDumpAfterFullGC                       = false                               {manageable}\n     bool HeapDumpBeforeFullGC                      = false                               {manageable}\n     bool HeapDumpOnOutOfMemoryError                = false                               {manageable}\n    ccstr HeapDumpPath                              =                                     {manageable}\n    uintx HeapFirstMaximumCompactionCount           = 3                                   {product}\n    uintx HeapMaximumCompactionInterval             = 20                                  {product}\n    uintx HeapSizePerGCThread                       = 87241520                            {product}\n     bool IgnoreEmptyClassPaths                     = false                               {product}\n     bool IgnoreUnrecognizedVMOptions               = false                               {product}\n    uintx IncreaseFirstTierCompileThresholdAt       = 50                                  {product}\n     bool IncrementalInline                         = true                                {C2 product}\n    uintx InitialBootClassLoaderMetaspaceSize       = 4194304                             {product}\n    uintx InitialCodeCacheSize                      = 2555904                             {pd product}\n    uintx InitialHeapSize                          := 251658240                           {product}\n    uintx InitialRAMFraction                        = 64                                  {product}\n    uintx InitialSurvivorRatio                      = 8                                   {product}\n    uintx InitialTenuringThreshold                  = 7                                   {product}\n    uintx InitiatingHeapOccupancyPercent            = 45                                  {product}\n     bool Inline                                    = true                                {product}\n    ccstr InlineDataFile                            =                                     {product}\n     intx InlineSmallCode                           = 2000                                {pd product}\n     bool InlineSynchronizedMethods                 = true                                {C1 product}\n     bool InsertMemBarAfterArraycopy                = true                                {C2 product}\n     intx InteriorEntryAlignment                    = 16                                  {C2 pd product}\n     intx InterpreterProfilePercentage              = 33                                  {product}\n     bool JNIDetachReleasesMonitors                 = true                                {product}\n     bool JavaMonitorsInStackTrace                  = true                                {product}\n     intx JavaPriority10_To_OSPriority              = -1                                  {product}\n     intx JavaPriority1_To_OSPriority               = -1                                  {product}\n     intx JavaPriority2_To_OSPriority               = -1                                  {product}\n     intx JavaPriority3_To_OSPriority               = -1                                  {product}\n     intx JavaPriority4_To_OSPriority               = -1                                  {product}\n     intx JavaPriority5_To_OSPriority               = -1                                  {product}\n     intx JavaPriority6_To_OSPriority               = -1                                  {product}\n     intx JavaPriority7_To_OSPriority               = -1                                  {product}\n     intx JavaPriority8_To_OSPriority               = -1                                  {product}\n     intx JavaPriority9_To_OSPriority               = -1                                  {product}\n     bool LIRFillDelaySlots                         = false                               {C1 pd product}\n    uintx LargePageHeapSizeThreshold                = 134217728                           {product}\n    uintx LargePageSizeInBytes                      = 0                                   {product}\n     bool LazyBootClassLoader                       = true                                {product}\n     intx LiveNodeCountInliningCutoff               = 40000                               {C2 product}\n     bool LogCommercialFeatures                     = false                               {product}\n     intx LoopMaxUnroll                             = 16                                  {C2 product}\n     intx LoopOptsCount                             = 43                                  {C2 product}\n     intx LoopUnrollLimit                           = 60                                  {C2 pd product}\n     intx LoopUnrollMin                             = 4                                   {C2 product}\n     bool LoopUnswitching                           = true                                {C2 product}\n     bool ManagementServer                          = false                               {product}\n    uintx MarkStackSize                             = 4194304                             {product}\n    uintx MarkStackSizeMax                          = 536870912                           {product}\n    uintx MarkSweepAlwaysCompactCount               = 4                                   {product}\n    uintx MarkSweepDeadRatio                        = 1                                   {product}\n     intx MaxBCEAEstimateLevel                      = 5                                   {product}\n     intx MaxBCEAEstimateSize                       = 150                                 {product}\n    uintx MaxDirectMemorySize                       = 0                                   {product}\n     bool MaxFDLimit                                = true                                {product}\n    uintx MaxGCMinorPauseMillis                     = 4294967295                          {product}\n    uintx MaxGCPauseMillis                          = 4294967295                          {product}\n    uintx MaxHeapFreeRatio                          = 100                                 {manageable}\n    uintx MaxHeapSize                              := 4009754624                          {product}\n     intx MaxInlineLevel                            = 9                                   {product}\n     intx MaxInlineSize                             = 35                                  {product}\n     intx MaxJNILocalCapacity                       = 65536                               {product}\n     intx MaxJavaStackTraceDepth                    = 1024                                {product}\n     intx MaxJumpTableSize                          = 65000                               {C2 product}\n     intx MaxJumpTableSparseness                    = 5                                   {C2 product}\n     intx MaxLabelRootDepth                         = 1100                                {C2 product}\n     intx MaxLoopPad                                = 15                                  {C2 product}\n    uintx MaxMetaspaceExpansion                     = 5451776                             {product}\n    uintx MaxMetaspaceFreeRatio                     = 70                                  {product}\n    uintx MaxMetaspaceSize                          = 4294901760                          {product}\n    uintx MaxNewSize                               := 1336410112                          {product}\n     intx MaxNodeLimit                              = 75000                               {C2 product}\n uint64_t MaxRAM                                    = 0                                   {pd product}\n    uintx MaxRAMFraction                            = 4                                   {product}\n     intx MaxRecursiveInlineLevel                   = 1                                   {product}\n    uintx MaxTenuringThreshold                      = 15                                  {product}\n     intx MaxTrivialSize                            = 6                                   {product}\n     intx MaxVectorSize                             = 16                                  {C2 product}\n    uintx MetaspaceSize                             = 21807104                            {pd product}\n     bool MethodFlushing                            = true                                {product}\n    uintx MinHeapDeltaBytes                        := 524288                              {product}\n    uintx MinHeapFreeRatio                          = 0                                   {manageable}\n     intx MinInliningThreshold                      = 250                                 {product}\n     intx MinJumpTableSize                          = 10                                  {C2 pd product}\n    uintx MinMetaspaceExpansion                     = 339968                              {product}\n    uintx MinMetaspaceFreeRatio                     = 40                                  {product}\n    uintx MinRAMFraction                            = 2                                   {product}\n    uintx MinSurvivorRatio                          = 3                                   {product}\n    uintx MinTLABSize                               = 2048                                {product}\n     intx MonitorBound                              = 0                                   {product}\n     bool MonitorInUseLists                         = false                               {product}\n     intx MultiArrayExpandLimit                     = 6                                   {C2 product}\n     bool MustCallLoadClassInternal                 = false                               {product}\n    uintx NUMAChunkResizeWeight                     = 20                                  {product}\n    uintx NUMAInterleaveGranularity                 = 2097152                             {product}\n    uintx NUMAPageScanRate                          = 256                                 {product}\n    uintx NUMASpaceResizeRate                       = 1073741824                          {product}\n     bool NUMAStats                                 = false                               {product}\n    ccstr NativeMemoryTracking                      = off                                 {product}\n     bool NeedsDeoptSuspend                         = false                               {pd product}\n     bool NeverActAsServerClassMachine              = false                               {pd product}\n     bool NeverTenure                               = false                               {product}\n    uintx NewRatio                                  = 2                                   {product}\n    uintx NewSize                                  := 83886080                            {product}\n    uintx NewSizeThreadIncrease                     = 5320                                {pd product}\n     intx NmethodSweepActivity                      = 10                                  {product}\n     intx NmethodSweepCheckInterval                 = 5                                   {product}\n     intx NmethodSweepFraction                      = 16                                  {product}\n     intx NodeLimitFudgeFactor                      = 2000                                {C2 product}\n    uintx NumberOfGCLogFiles                        = 0                                   {product}\n     intx NumberOfLoopInstrToAlign                  = 4                                   {C2 product}\n     intx ObjectAlignmentInBytes                    = 8                                   {lp64_product}\n    uintx OldPLABSize                               = 1024                                {product}\n    uintx OldPLABWeight                             = 50                                  {product}\n    uintx OldSize                                  := 167772160                           {product}\n     bool OmitStackTraceInFastThrow                 = true                                {product}\nccstrlist OnError                                   =                                     {product}\nccstrlist OnOutOfMemoryError                        =                                     {product}\n     intx OnStackReplacePercentage                  = 140                                 {pd product}\n     bool OptimizeFill                              = true                                {C2 product}\n     bool OptimizePtrCompare                        = true                                {C2 product}\n     bool OptimizeStringConcat                      = true                                {C2 product}\n     bool OptoBundling                              = false                               {C2 pd product}\n     intx OptoLoopAlignment                         = 16                                  {pd product}\n     bool OptoScheduling                            = false                               {C2 pd product}\n    uintx PLABWeight                                = 75                                  {product}\n     bool PSChunkLargeArrays                        = true                                {product}\n     intx ParGCArrayScanChunk                       = 50                                  {product}\n    uintx ParGCDesiredObjsFromOverflowList          = 20                                  {product}\n     bool ParGCTrimOverflow                         = true                                {product}\n     bool ParGCUseLocalOverflow                     = false                               {product}\n    uintx ParallelGCBufferWastePct                  = 10                                  {product}\n    uintx ParallelGCThreads                         = 8                                   {product}\n     bool ParallelGCVerbose                         = false                               {product}\n    uintx ParallelOldDeadWoodLimiterMean            = 50                                  {product}\n    uintx ParallelOldDeadWoodLimiterStdDev          = 80                                  {product}\n     bool ParallelRefProcBalancingEnabled           = true                                {product}\n     bool ParallelRefProcEnabled                    = false                               {product}\n     bool PartialPeelAtUnsignedTests                = true                                {C2 product}\n     bool PartialPeelLoop                           = true                                {C2 product}\n     intx PartialPeelNewPhiDelta                    = 0                                   {C2 product}\n    uintx PausePadding                              = 1                                   {product}\n     intx PerBytecodeRecompilationCutoff            = 200                                 {product}\n     intx PerBytecodeTrapLimit                      = 4                                   {product}\n     intx PerMethodRecompilationCutoff              = 400                                 {product}\n     intx PerMethodTrapLimit                        = 100                                 {product}\n     bool PerfAllowAtExitRegistration               = false                               {product}\n     bool PerfBypassFileSystemCheck                 = false                               {product}\n     intx PerfDataMemorySize                        = 32768                               {product}\n     intx PerfDataSamplingInterval                  = 50                                  {product}\n    ccstr PerfDataSaveFile                          =                                     {product}\n     bool PerfDataSaveToFile                        = false                               {product}\n     bool PerfDisableSharedMem                      = false                               {product}\n     intx PerfMaxStringConstLength                  = 1024                                {product}\n     intx PreInflateSpin                            = 10                                  {pd product}\n     bool PreferInterpreterNativeStubs              = false                               {pd product}\n     intx PrefetchCopyIntervalInBytes               = 576                                 {product}\n     intx PrefetchFieldsAhead                       = 1                                   {product}\n     intx PrefetchScanIntervalInBytes               = 576                                 {product}\n     bool PreserveAllAnnotations                    = false                               {product}\n     bool PreserveFramePointer                      = false                               {pd product}\n    uintx PretenureSizeThreshold                    = 0                                   {product}\n     bool PrintAdaptiveSizePolicy                   = false                               {product}\n     bool PrintCMSInitiationStatistics              = false                               {product}\n     intx PrintCMSStatistics                        = 0                                   {product}\n     bool PrintClassHistogram                       = false                               {manageable}\n     bool PrintClassHistogramAfterFullGC            = false                               {manageable}\n     bool PrintClassHistogramBeforeFullGC           = false                               {manageable}\n     bool PrintCodeCache                            = false                               {product}\n     bool PrintCodeCacheOnCompilation               = false                               {product}\n     bool PrintCommandLineFlags                     = false                               {product}\n     bool PrintCompilation                          = false                               {product}\n     bool PrintConcurrentLocks                      = false                               {manageable}\n     intx PrintFLSCensus                            = 0                                   {product}\n     intx PrintFLSStatistics                        = 0                                   {product}\n     bool PrintFlagsFinal                          := true                                {product}\n     bool PrintFlagsInitial                         = false                               {product}\n     bool PrintGC                                   = false                               {manageable}\n     bool PrintGCApplicationConcurrentTime          = false                               {product}\n     bool PrintGCApplicationStoppedTime             = false                               {product}\n     bool PrintGCCause                              = true                                {product}\n     bool PrintGCDateStamps                         = false                               {manageable}\n     bool PrintGCDetails                            = false                               {manageable}\n     bool PrintGCID                                 = false                               {manageable}\n     bool PrintGCTaskTimeStamps                     = false                               {product}\n     bool PrintGCTimeStamps                         = false                               {manageable}\n     bool PrintHeapAtGC                             = false                               {product rw}\n     bool PrintHeapAtGCExtended                     = false                               {product rw}\n     bool PrintHeapAtSIGBREAK                       = true                                {product}\n     bool PrintJNIGCStalls                          = false                               {product}\n     bool PrintJNIResolving                         = false                               {product}\n     bool PrintOldPLAB                              = false                               {product}\n     bool PrintOopAddress                           = false                               {product}\n     bool PrintPLAB                                 = false                               {product}\n     bool PrintParallelOldGCPhaseTimes              = false                               {product}\n     bool PrintPromotionFailure                     = false                               {product}\n     bool PrintReferenceGC                          = false                               {product}\n     bool PrintSafepointStatistics                  = false                               {product}\n     intx PrintSafepointStatisticsCount             = 300                                 {product}\n     intx PrintSafepointStatisticsTimeout           = -1                                  {product}\n     bool PrintSharedArchiveAndExit                 = false                               {product}\n     bool PrintSharedDictionary                     = false                               {product}\n     bool PrintSharedSpaces                         = false                               {product}\n     bool PrintStringDeduplicationStatistics        = false                               {product}\n     bool PrintStringTableStatistics                = false                               {product}\n     bool PrintTLAB                                 = false                               {product}\n     bool PrintTenuringDistribution                 = false                               {product}\n     bool PrintTieredEvents                         = false                               {product}\n     bool PrintVMOptions                            = false                               {product}\n     bool PrintVMQWaitTime                          = false                               {product}\n     bool PrintWarnings                             = true                                {product}\n    uintx ProcessDistributionStride                 = 4                                   {product}\n     bool ProfileInterpreter                        = true                                {pd product}\n     bool ProfileIntervals                          = false                               {product}\n     intx ProfileIntervalsTicks                     = 100                                 {product}\n     intx ProfileMaturityPercentage                 = 20                                  {product}\n     bool ProfileVM                                 = false                               {product}\n     bool ProfilerPrintByteCodeStatistics           = false                               {product}\n     bool ProfilerRecordPC                          = false                               {product}\n    uintx PromotedPadding                           = 3                                   {product}\n    uintx QueuedAllocationWarningCount              = 0                                   {product}\n    uintx RTMRetryCount                             = 5                                   {ARCH product}\n     bool RangeCheckElimination                     = true                                {product}\n     intx ReadPrefetchInstr                         = 0                                   {ARCH product}\n     bool ReassociateInvariants                     = true                                {C2 product}\n     bool ReduceBulkZeroing                         = true                                {C2 product}\n     bool ReduceFieldZeroing                        = true                                {C2 product}\n     bool ReduceInitialCardMarks                    = true                                {C2 product}\n     bool ReduceSignalUsage                         = false                               {product}\n     intx RefDiscoveryPolicy                        = 0                                   {product}\n     bool ReflectionWrapResolutionErrors            = true                                {product}\n     bool RegisterFinalizersAtInit                  = true                                {product}\n     bool RelaxAccessControlCheck                   = false                               {product}\n    ccstr ReplayDataFile                            =                                     {product}\n     bool RequireSharedSpaces                       = false                               {product}\n    uintx ReservedCodeCacheSize                     = 251658240                           {pd product}\n     bool ResizeOldPLAB                             = true                                {product}\n     bool ResizePLAB                                = true                                {product}\n     bool ResizeTLAB                                = true                                {pd product}\n     bool RestoreMXCSROnJNICalls                    = false                               {product}\n     bool RestrictContended                         = true                                {product}\n     bool RewriteBytecodes                          = true                                {pd product}\n     bool RewriteFrequentPairs                      = true                                {pd product}\n     intx SafepointPollOffset                       = 256                                 {C1 pd product}\n     intx SafepointSpinBeforeYield                  = 2000                                {product}\n     bool SafepointTimeout                          = false                               {product}\n     intx SafepointTimeoutDelay                     = 10000                               {product}\n     bool ScavengeBeforeFullGC                      = true                                {product}\n     intx SelfDestructTimer                         = 0                                   {product}\n    uintx SharedBaseAddress                         = 0                                   {product}\n    ccstr SharedClassListFile                       =                                     {product}\n    uintx SharedMiscCodeSize                        = 122880                              {product}\n    uintx SharedMiscDataSize                        = 4194304                             {product}\n    uintx SharedReadOnlySize                        = 16777216                            {product}\n    uintx SharedReadWriteSize                       = 16777216                            {product}\n     bool ShowMessageBoxOnError                     = false                               {product}\n     intx SoftRefLRUPolicyMSPerMB                   = 1000                                {product}\n     bool SpecialEncodeISOArray                     = true                                {C2 product}\n     bool SplitIfBlocks                             = true                                {C2 product}\n     intx StackRedPages                             = 1                                   {pd product}\n     intx StackShadowPages                          = 6                                   {pd product}\n     bool StackTraceInThrowable                     = true                                {product}\n     intx StackYellowPages                          = 3                                   {pd product}\n     bool StartAttachListener                       = false                               {product}\n     intx StarvationMonitorInterval                 = 200                                 {product}\n     bool StressLdcRewrite                          = false                               {product}\n    uintx StringDeduplicationAgeThreshold           = 3                                   {product}\n    uintx StringTableSize                           = 60013                               {product}\n     bool SuppressFatalErrorMessage                 = false                               {product}\n    uintx SurvivorPadding                           = 3                                   {product}\n    uintx SurvivorRatio                             = 8                                   {product}\n     intx SuspendRetryCount                         = 50                                  {product}\n     intx SuspendRetryDelay                         = 5                                   {product}\n     intx SyncFlags                                 = 0                                   {product}\n    ccstr SyncKnobs                                 =                                     {product}\n     intx SyncVerbose                               = 0                                   {product}\n    uintx TLABAllocationWeight                      = 35                                  {product}\n    uintx TLABRefillWasteFraction                   = 64                                  {product}\n    uintx TLABSize                                  = 0                                   {product}\n     bool TLABStats                                 = true                                {product}\n    uintx TLABWasteIncrement                        = 4                                   {product}\n    uintx TLABWasteTargetPercent                    = 1                                   {product}\n    uintx TargetPLABWastePct                        = 10                                  {product}\n    uintx TargetSurvivorRatio                       = 50                                  {product}\n    uintx TenuredGenerationSizeIncrement            = 20                                  {product}\n    uintx TenuredGenerationSizeSupplement           = 80                                  {product}\n    uintx TenuredGenerationSizeSupplementDecay      = 2                                   {product}\n     intx ThreadPriorityPolicy                      = 0                                   {product}\n     bool ThreadPriorityVerbose                     = false                               {product}\n    uintx ThreadSafetyMargin                        = 52428800                            {product}\n     intx ThreadStackSize                           = 0                                   {pd product}\n    uintx ThresholdTolerance                        = 10                                  {product}\n     intx Tier0BackedgeNotifyFreqLog                = 10                                  {product}\n     intx Tier0InvokeNotifyFreqLog                  = 7                                   {product}\n     intx Tier0ProfilingStartPercentage             = 200                                 {product}\n     intx Tier23InlineeNotifyFreqLog                = 20                                  {product}\n     intx Tier2BackEdgeThreshold                    = 0                                   {product}\n     intx Tier2BackedgeNotifyFreqLog                = 14                                  {product}\n     intx Tier2CompileThreshold                     = 0                                   {product}\n     intx Tier2InvokeNotifyFreqLog                  = 11                                  {product}\n     intx Tier3BackEdgeThreshold                    = 60000                               {product}\n     intx Tier3BackedgeNotifyFreqLog                = 13                                  {product}\n     intx Tier3CompileThreshold                     = 2000                                {product}\n     intx Tier3DelayOff                             = 2                                   {product}\n     intx Tier3DelayOn                              = 5                                   {product}\n     intx Tier3InvocationThreshold                  = 200                                 {product}\n     intx Tier3InvokeNotifyFreqLog                  = 10                                  {product}\n     intx Tier3LoadFeedback                         = 5                                   {product}\n     intx Tier3MinInvocationThreshold               = 100                                 {product}\n     intx Tier4BackEdgeThreshold                    = 40000                               {product}\n     intx Tier4CompileThreshold                     = 15000                               {product}\n     intx Tier4InvocationThreshold                  = 5000                                {product}\n     intx Tier4LoadFeedback                         = 3                                   {product}\n     intx Tier4MinInvocationThreshold               = 600                                 {product}\n     bool TieredCompilation                         = true                                {pd product}\n     intx TieredCompileTaskTimeout                  = 50                                  {product}\n     intx TieredRateUpdateMaxTime                   = 25                                  {product}\n     intx TieredRateUpdateMinTime                   = 1                                   {product}\n     intx TieredStopAtLevel                         = 4                                   {product}\n     bool TimeLinearScan                            = false                               {C1 product}\n     bool TraceBiasedLocking                        = false                               {product}\n     bool TraceClassLoading                         = false                               {product rw}\n     bool TraceClassLoadingPreorder                 = false                               {product}\n     bool TraceClassPaths                           = false                               {product}\n     bool TraceClassResolution                      = false                               {product}\n     bool TraceClassUnloading                       = false                               {product rw}\n     bool TraceDynamicGCThreads                     = false                               {product}\n     bool TraceGen0Time                             = false                               {product}\n     bool TraceGen1Time                             = false                               {product}\n    ccstr TraceJVMTI                                =                                     {product}\n     bool TraceLoaderConstraints                    = false                               {product rw}\n     bool TraceMetadataHumongousAllocation          = false                               {product}\n     bool TraceMonitorInflation                     = false                               {product}\n     bool TraceParallelOldGCTasks                   = false                               {product}\n     intx TraceRedefineClasses                      = 0                                   {product}\n     bool TraceSafepointCleanupTime                 = false                               {product}\n     bool TraceSharedLookupCache                    = false                               {product}\n     bool TraceSuspendWaitFailures                  = false                               {product}\n     intx TrackedInitializationLimit                = 50                                  {C2 product}\n     bool TransmitErrorReport                       = false                               {product}\n     bool TrapBasedNullChecks                       = false                               {pd product}\n     bool TrapBasedRangeChecks                      = false                               {C2 pd product}\n     intx TypeProfileArgsLimit                      = 2                                   {product}\n    uintx TypeProfileLevel                          = 111                                 {pd product}\n     intx TypeProfileMajorReceiverPercent           = 90                                  {C2 product}\n     intx TypeProfileParmsLimit                     = 2                                   {product}\n     intx TypeProfileWidth                          = 2                                   {product}\n     intx UnguardOnExecutionViolation               = 0                                   {product}\n     bool UnlinkSymbolsALot                         = false                               {product}\n     bool Use486InstrsOnly                          = false                               {ARCH product}\n     bool UseAES                                    = true                                {product}\n     bool UseAESIntrinsics                          = true                                {product}\n     intx UseAVX                                    = 2                                   {ARCH product}\n     bool UseAdaptiveGCBoundary                     = false                               {product}\n     bool UseAdaptiveGenerationSizePolicyAtMajorCollection  = true                                {product}\n     bool UseAdaptiveGenerationSizePolicyAtMinorCollection  = true                                {product}\n     bool UseAdaptiveNUMAChunkSizing                = true                                {product}\n     bool UseAdaptiveSizeDecayMajorGCCost           = true                                {product}\n     bool UseAdaptiveSizePolicy                     = true                                {product}\n     bool UseAdaptiveSizePolicyFootprintGoal        = true                                {product}\n     bool UseAdaptiveSizePolicyWithSystemGC         = false                               {product}\n     bool UseAddressNop                             = true                                {ARCH product}\n     bool UseAltSigs                                = false                               {product}\n     bool UseAutoGCSelectPolicy                     = false                               {product}\n     bool UseBMI1Instructions                       = true                                {ARCH product}\n     bool UseBMI2Instructions                       = false                               {ARCH product}\n     bool UseBiasedLocking                          = true                                {product}\n     bool UseBimorphicInlining                      = true                                {C2 product}\n     bool UseBoundThreads                           = true                                {product}\n     bool UseCLMUL                                  = true                                {ARCH product}\n     bool UseCMSBestFit                             = true                                {product}\n     bool UseCMSCollectionPassing                   = true                                {product}\n     bool UseCMSCompactAtFullCollection             = true                                {product}\n     bool UseCMSInitiatingOccupancyOnly             = false                               {product}\n     bool UseCRC32Intrinsics                        = true                                {product}\n     bool UseCodeCacheFlushing                      = true                                {product}\n     bool UseCompiler                               = true                                {product}\n     bool UseCompilerSafepoints                     = true                                {product}\n     bool UseCompressedClassPointers               := true                                {lp64_product}\n     bool UseCompressedOops                        := true                                {lp64_product}\n     bool UseConcMarkSweepGC                        = false                               {product}\n     bool UseCondCardMark                           = false                               {C2 product}\n     bool UseCountLeadingZerosInstruction           = true                                {ARCH product}\n     bool UseCountTrailingZerosInstruction          = true                                {ARCH product}\n     bool UseCountedLoopSafepoints                  = false                               {C2 product}\n     bool UseCounterDecay                           = true                                {product}\n     bool UseDivMod                                 = true                                {C2 product}\n     bool UseDynamicNumberOfGCThreads               = false                               {product}\n     bool UseFPUForSpilling                         = false                               {C2 product}\n     bool UseFastAccessorMethods                    = false                               {product}\n     bool UseFastEmptyMethods                       = false                               {product}\n     bool UseFastJNIAccessors                       = true                                {product}\n     bool UseFastStosb                              = false                               {ARCH product}\n     bool UseG1GC                                   = false                               {product}\n     bool UseGCLogFileRotation                      = false                               {product}\n     bool UseGCOverheadLimit                        = true                                {product}\n     bool UseGCTaskAffinity                         = false                               {product}\n     bool UseHeavyMonitors                          = false                               {product}\n     bool UseInlineCaches                           = true                                {product}\n     bool UseInterpreter                            = true                                {product}\n     bool UseJumpTables                             = true                                {C2 product}\n     bool UseLWPSynchronization                     = true                                {product}\n     bool UseLargePages                             = false                               {pd product}\n     bool UseLargePagesInMetaspace                  = false                               {product}\n     bool UseLargePagesIndividualAllocation        := false                               {pd product}\n     bool UseLockedTracing                          = false                               {product}\n     bool UseLoopCounter                            = true                                {product}\n     bool UseLoopInvariantCodeMotion                = true                                {C1 product}\n     bool UseLoopPredicate                          = true                                {C2 product}\n     bool UseMathExactIntrinsics                    = true                                {C2 product}\n     bool UseMaximumCompactionOnSystemGC            = true                                {product}\n     bool UseMembar                                 = false                               {pd product}\n     bool UseMontgomeryMultiplyIntrinsic            = false                               {C2 product}\n     bool UseMontgomerySquareIntrinsic              = false                               {C2 product}\n     bool UseMulAddIntrinsic                        = false                               {C2 product}\n     bool UseMultiplyToLenIntrinsic                 = true                                {C2 product}\n     bool UseNUMA                                   = false                               {product}\n     bool UseNUMAInterleaving                       = false                               {product}\n     bool UseNewLongLShift                          = true                                {ARCH product}\n     bool UseOSErrorReporting                       = false                               {pd product}\n     bool UseOldInlining                            = true                                {C2 product}\n     bool UseOnStackReplacement                     = true                                {pd product}\n     bool UseOnlyInlinedBimorphic                   = true                                {C2 product}\n     bool UseOptoBiasInlining                       = true                                {C2 product}\n     bool UsePSAdaptiveSurvivorSizePolicy           = true                                {product}\n     bool UseParNewGC                               = false                               {product}\n     bool UseParallelGC                            := true                                {product}\n     bool UseParallelOldGC                          = true                                {product}\n     bool UsePerfData                               = true                                {product}\n     bool UsePopCountInstruction                    = true                                {product}\n     bool UseRDPCForConstantTableBase               = false                               {C2 product}\n     bool UseRTMDeopt                               = false                               {ARCH product}\n     bool UseRTMLocking                             = false                               {ARCH product}\n     bool UseSHA                                    = false                               {product}\n     bool UseSHA1Intrinsics                         = false                               {product}\n     bool UseSHA256Intrinsics                       = false                               {product}\n     bool UseSHA512Intrinsics                       = false                               {product}\n     intx UseSSE                                    = 4                                   {product}\n     bool UseSSE42Intrinsics                        = true                                {product}\n     bool UseSerialGC                               = false                               {product}\n     bool UseSharedSpaces                           = false                               {product}\n     bool UseSignalChaining                         = true                                {product}\n     bool UseSquareToLenIntrinsic                   = false                               {C2 product}\n     bool UseStoreImmI16                            = true                                {ARCH product}\n     bool UseStringDeduplication                    = false                               {product}\n     bool UseSuperWord                              = true                                {C2 product}\n     bool UseTLAB                                   = true                                {pd product}\n     bool UseThreadPriorities                       = true                                {pd product}\n     bool UseTypeProfile                            = true                                {product}\n     bool UseTypeSpeculation                        = true                                {C2 product}\n     bool UseUTCFileTimestamp                       = true                                {product}\n     bool UseUnalignedLoadStores                    = false                               {ARCH product}\n     bool UseVMInterruptibleIO                      = false                               {product}\n     bool UseXMMForArrayCopy                        = false                               {product}\n     bool UseXmmI2D                                 = true                                {ARCH product}\n     bool UseXmmI2F                                 = true                                {ARCH product}\n     bool UseXmmLoadAndClearUpper                   = true                                {ARCH product}\n     bool UseXmmRegToRegMoveAll                     = true                                {ARCH product}\n     bool VMThreadHintNoPreempt                     = false                               {product}\n     intx VMThreadPriority                          = -1                                  {product}\n     intx VMThreadStackSize                         = 0                                   {pd product}\n     intx ValueMapInitialSize                       = 11                                  {C1 product}\n     intx ValueMapMaxLoopSize                       = 8                                   {C1 product}\n     intx ValueSearchLimit                          = 1000                                {C2 product}\n     bool VerifyMergedCPBytecodes                   = true                                {product}\n     bool VerifySharedSpaces                        = false                               {product}\n     intx WorkAroundNPTLTimedWaitHang               = 1                                   {product}\n    uintx YoungGenerationSizeIncrement              = 20                                  {product}\n    uintx YoungGenerationSizeSupplement             = 80                                  {product}\n    uintx YoungGenerationSizeSupplementDecay        = 8                                   {product}\n    uintx YoungPLABSize                             = 4096                                {product}\n     bool ZeroTLAB                                  = false                               {product}\n     intx hashCode                                  = 5                                   {product}"
  },
  {
    "path": "mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Maven2 Start Up Batch script\n#\n# Required ENV vars:\n# ------------------\n#   JAVA_HOME - location of a JDK home dir\n#\n# Optional ENV vars\n# -----------------\n#   M2_HOME - location of maven2's installed home dir\n#   MAVEN_OPTS - parameters passed to the Java VM when running Maven\n#     e.g. to debug Maven itself, use\n#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n# ----------------------------------------------------------------------------\n\nif [ -z \"$MAVEN_SKIP_RC\" ] ; then\n\n  if [ -f /etc/mavenrc ] ; then\n    . /etc/mavenrc\n  fi\n\n  if [ -f \"$HOME/.mavenrc\" ] ; then\n    . \"$HOME/.mavenrc\"\n  fi\n\nfi\n\n# OS specific support.  $var _must_ be set to either true or false.\ncygwin=false;\ndarwin=false;\nmingw=false\ncase \"`uname`\" in\n  CYGWIN*) cygwin=true ;;\n  MINGW*) mingw=true;;\n  Darwin*) darwin=true\n    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home\n    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html\n    if [ -z \"$JAVA_HOME\" ]; then\n      if [ -x \"/usr/libexec/java_home\" ]; then\n        export JAVA_HOME=\"`/usr/libexec/java_home`\"\n      else\n        export JAVA_HOME=\"/Library/Java/Home\"\n      fi\n    fi\n    ;;\nesac\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  if [ -r /etc/gentoo-release ] ; then\n    JAVA_HOME=`java-config --jre-home`\n  fi\nfi\n\nif [ -z \"$M2_HOME\" ] ; then\n  ## resolve links - $0 may be a link to maven's home\n  PRG=\"$0\"\n\n  # need this for relative symlinks\n  while [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n      PRG=\"$link\"\n    else\n      PRG=\"`dirname \"$PRG\"`/$link\"\n    fi\n  done\n\n  saveddir=`pwd`\n\n  M2_HOME=`dirname \"$PRG\"`/..\n\n  # make it fully qualified\n  M2_HOME=`cd \"$M2_HOME\" && pwd`\n\n  cd \"$saveddir\"\n  # echo Using m2 at $M2_HOME\nfi\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched\nif $cygwin ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --unix \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --unix \"$CLASSPATH\"`\nfi\n\n# For Mingw, ensure paths are in UNIX format before anything is touched\nif $mingw ; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=\"`(cd \"$M2_HOME\"; pwd)`\"\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=\"`(cd \"$JAVA_HOME\"; pwd)`\"\nfi\n\nif [ -z \"$JAVA_HOME\" ]; then\n  javaExecutable=\"`which javac`\"\n  if [ -n \"$javaExecutable\" ] && ! [ \"`expr \\\"$javaExecutable\\\" : '\\([^ ]*\\)'`\" = \"no\" ]; then\n    # readlink(1) is not available as standard on Solaris 10.\n    readLink=`which readlink`\n    if [ ! `expr \"$readLink\" : '\\([^ ]*\\)'` = \"no\" ]; then\n      if $darwin ; then\n        javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n        javaExecutable=\"`cd \\\"$javaHome\\\" && pwd -P`/javac\"\n      else\n        javaExecutable=\"`readlink -f \\\"$javaExecutable\\\"`\"\n      fi\n      javaHome=\"`dirname \\\"$javaExecutable\\\"`\"\n      javaHome=`expr \"$javaHome\" : '\\(.*\\)/bin'`\n      JAVA_HOME=\"$javaHome\"\n      export JAVA_HOME\n    fi\n  fi\nfi\n\nif [ -z \"$JAVACMD\" ] ; then\n  if [ -n \"$JAVA_HOME\"  ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n  else\n    JAVACMD=\"`which java`\"\n  fi\nfi\n\nif [ ! -x \"$JAVACMD\" ] ; then\n  echo \"Error: JAVA_HOME is not defined correctly.\" >&2\n  echo \"  We cannot execute $JAVACMD\" >&2\n  exit 1\nfi\n\nif [ -z \"$JAVA_HOME\" ] ; then\n  echo \"Warning: JAVA_HOME environment variable is not set.\"\nfi\n\nCLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher\n\n# traverses directory structure from process work directory to filesystem root\n# first directory with .mvn subdirectory is considered project base directory\nfind_maven_basedir() {\n\n  if [ -z \"$1\" ]\n  then\n    echo \"Path not specified to find_maven_basedir\"\n    return 1\n  fi\n\n  basedir=\"$1\"\n  wdir=\"$1\"\n  while [ \"$wdir\" != '/' ] ; do\n    if [ -d \"$wdir\"/.mvn ] ; then\n      basedir=$wdir\n      break\n    fi\n    # workaround for JBEAP-8937 (on Solaris 10/Sparc)\n    if [ -d \"${wdir}\" ]; then\n      wdir=`cd \"$wdir/..\"; pwd`\n    fi\n    # end of workaround\n  done\n  echo \"${basedir}\"\n}\n\n# concatenates all lines of a file\nconcat_lines() {\n  if [ -f \"$1\" ]; then\n    echo \"$(tr -s '\\n' ' ' < \"$1\")\"\n  fi\n}\n\nBASE_DIR=`find_maven_basedir \"$(pwd)\"`\nif [ -z \"$BASE_DIR\" ]; then\n  exit 1;\nfi\n\n##########################################################################################\n# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n# This allows using the maven wrapper in projects that prohibit checking in binary data.\n##########################################################################################\nif [ -r \"$BASE_DIR/.mvn/wrapper/maven-wrapper.jar\" ]; then\n    if [ \"$MVNW_VERBOSE\" = true ]; then\n      echo \"Found .mvn/wrapper/maven-wrapper.jar\"\n    fi\nelse\n    if [ \"$MVNW_VERBOSE\" = true ]; then\n      echo \"Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ...\"\n    fi\n    if [ -n \"$MVNW_REPOURL\" ]; then\n      jarUrl=\"$MVNW_REPOURL/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar\"\n    else\n      jarUrl=\"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar\"\n    fi\n    while IFS=\"=\" read key value; do\n      case \"$key\" in (wrapperUrl) jarUrl=\"$value\"; break ;;\n      esac\n    done < \"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties\"\n    if [ \"$MVNW_VERBOSE\" = true ]; then\n      echo \"Downloading from: $jarUrl\"\n    fi\n    wrapperJarPath=\"$BASE_DIR/.mvn/wrapper/maven-wrapper.jar\"\n    if $cygwin; then\n      wrapperJarPath=`cygpath --path --windows \"$wrapperJarPath\"`\n    fi\n\n    if command -v wget > /dev/null; then\n        if [ \"$MVNW_VERBOSE\" = true ]; then\n          echo \"Found wget ... using wget\"\n        fi\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            wget \"$jarUrl\" -O \"$wrapperJarPath\"\n        else\n            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD \"$jarUrl\" -O \"$wrapperJarPath\"\n        fi\n    elif command -v curl > /dev/null; then\n        if [ \"$MVNW_VERBOSE\" = true ]; then\n          echo \"Found curl ... using curl\"\n        fi\n        if [ -z \"$MVNW_USERNAME\" ] || [ -z \"$MVNW_PASSWORD\" ]; then\n            curl -o \"$wrapperJarPath\" \"$jarUrl\" -f\n        else\n            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o \"$wrapperJarPath\" \"$jarUrl\" -f\n        fi\n        \n    else\n        if [ \"$MVNW_VERBOSE\" = true ]; then\n          echo \"Falling back to using Java to download\"\n        fi\n        javaClass=\"$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java\"\n        # For Cygwin, switch paths to Windows format before running javac\n        if $cygwin; then\n          javaClass=`cygpath --path --windows \"$javaClass\"`\n        fi\n        if [ -e \"$javaClass\" ]; then\n            if [ ! -e \"$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class\" ]; then\n                if [ \"$MVNW_VERBOSE\" = true ]; then\n                  echo \" - Compiling MavenWrapperDownloader.java ...\"\n                fi\n                # Compiling the Java class\n                (\"$JAVA_HOME/bin/javac\" \"$javaClass\")\n            fi\n            if [ -e \"$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class\" ]; then\n                # Running the downloader\n                if [ \"$MVNW_VERBOSE\" = true ]; then\n                  echo \" - Running MavenWrapperDownloader.java ...\"\n                fi\n                (\"$JAVA_HOME/bin/java\" -cp .mvn/wrapper MavenWrapperDownloader \"$MAVEN_PROJECTBASEDIR\")\n            fi\n        fi\n    fi\nfi\n##########################################################################################\n# End of extension\n##########################################################################################\n\nexport MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-\"$BASE_DIR\"}\nif [ \"$MVNW_VERBOSE\" = true ]; then\n  echo $MAVEN_PROJECTBASEDIR\nfi\nMAVEN_OPTS=\"$(concat_lines \"$MAVEN_PROJECTBASEDIR/.mvn/jvm.config\") $MAVEN_OPTS\"\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin; then\n  [ -n \"$M2_HOME\" ] &&\n    M2_HOME=`cygpath --path --windows \"$M2_HOME\"`\n  [ -n \"$JAVA_HOME\" ] &&\n    JAVA_HOME=`cygpath --path --windows \"$JAVA_HOME\"`\n  [ -n \"$CLASSPATH\" ] &&\n    CLASSPATH=`cygpath --path --windows \"$CLASSPATH\"`\n  [ -n \"$MAVEN_PROJECTBASEDIR\" ] &&\n    MAVEN_PROJECTBASEDIR=`cygpath --path --windows \"$MAVEN_PROJECTBASEDIR\"`\nfi\n\nWRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nexec \"$JAVACMD\" \\\n  $MAVEN_OPTS \\\n  -classpath \"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar\" \\\n  \"-Dmaven.home=${M2_HOME}\" \"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}\" \\\n  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG \"$@\"\n"
  },
  {
    "path": "mvnw.cmd",
    "content": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software Foundation (ASF) under one\n@REM or more contributor license agreements.  See the NOTICE file\n@REM distributed with this work for additional information\n@REM regarding copyright ownership.  The ASF licenses this file\n@REM to you under the Apache License, Version 2.0 (the\n@REM \"License\"); you may not use this file except in compliance\n@REM with the License.  You may obtain a copy of the License at\n@REM\n@REM    https://www.apache.org/licenses/LICENSE-2.0\n@REM\n@REM Unless required by applicable law or agreed to in writing,\n@REM software distributed under the License is distributed on an\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n@REM KIND, either express or implied.  See the License for the\n@REM specific language governing permissions and limitations\n@REM under the License.\n@REM ----------------------------------------------------------------------------\n\n@REM ----------------------------------------------------------------------------\n@REM Maven2 Start Up Batch script\n@REM\n@REM Required ENV vars:\n@REM JAVA_HOME - location of a JDK home dir\n@REM\n@REM Optional ENV vars\n@REM M2_HOME - location of maven2's installed home dir\n@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands\n@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending\n@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven\n@REM     e.g. to debug Maven itself, use\n@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000\n@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files\n@REM ----------------------------------------------------------------------------\n\n@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'\n@echo off\n@REM set title of command window\ntitle %0\n@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'\n@if \"%MAVEN_BATCH_ECHO%\" == \"on\"  echo %MAVEN_BATCH_ECHO%\n\n@REM set %HOME% to equivalent of $HOME\nif \"%HOME%\" == \"\" (set \"HOME=%HOMEDRIVE%%HOMEPATH%\")\n\n@REM Execute a user defined script before this one\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPre\n@REM check for pre script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_pre.bat\" call \"%HOME%\\mavenrc_pre.bat\"\nif exist \"%HOME%\\mavenrc_pre.cmd\" call \"%HOME%\\mavenrc_pre.cmd\"\n:skipRcPre\n\n@setlocal\n\nset ERROR_CODE=0\n\n@REM To isolate internal variables from possible post scripts, we use another setlocal\n@setlocal\n\n@REM ==== START VALIDATION ====\nif not \"%JAVA_HOME%\" == \"\" goto OkJHome\n\necho.\necho Error: JAVA_HOME not found in your environment. >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n:OkJHome\nif exist \"%JAVA_HOME%\\bin\\java.exe\" goto init\n\necho.\necho Error: JAVA_HOME is set to an invalid directory. >&2\necho JAVA_HOME = \"%JAVA_HOME%\" >&2\necho Please set the JAVA_HOME variable in your environment to match the >&2\necho location of your Java installation. >&2\necho.\ngoto error\n\n@REM ==== END VALIDATION ====\n\n:init\n\n@REM Find the project base dir, i.e. the directory that contains the folder \".mvn\".\n@REM Fallback to current working directory if not found.\n\nset MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%\nIF NOT \"%MAVEN_PROJECTBASEDIR%\"==\"\" goto endDetectBaseDir\n\nset EXEC_DIR=%CD%\nset WDIR=%EXEC_DIR%\n:findBaseDir\nIF EXIST \"%WDIR%\"\\.mvn goto baseDirFound\ncd ..\nIF \"%WDIR%\"==\"%CD%\" goto baseDirNotFound\nset WDIR=%CD%\ngoto findBaseDir\n\n:baseDirFound\nset MAVEN_PROJECTBASEDIR=%WDIR%\ncd \"%EXEC_DIR%\"\ngoto endDetectBaseDir\n\n:baseDirNotFound\nset MAVEN_PROJECTBASEDIR=%EXEC_DIR%\ncd \"%EXEC_DIR%\"\n\n:endDetectBaseDir\n\nIF NOT EXIST \"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\" goto endReadAdditionalConfig\n\n@setlocal EnableExtensions EnableDelayedExpansion\nfor /F \"usebackq delims=\" %%a in (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\jvm.config\") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a\n@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%\n\n:endReadAdditionalConfig\n\nSET MAVEN_JAVA_EXE=\"%JAVA_HOME%\\bin\\java.exe\"\nset WRAPPER_JAR=\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.jar\"\nset WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain\n\nset DOWNLOAD_URL=\"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar\"\n\nFOR /F \"tokens=1,2 delims==\" %%A IN (\"%MAVEN_PROJECTBASEDIR%\\.mvn\\wrapper\\maven-wrapper.properties\") DO (\n    IF \"%%A\"==\"wrapperUrl\" SET DOWNLOAD_URL=%%B\n)\n\n@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central\n@REM This allows using the maven wrapper in projects that prohibit checking in binary data.\nif exist %WRAPPER_JAR% (\n    echo Found %WRAPPER_JAR%\n) else (\n\tif not \"%MVNW_REPOURL%\" == \"\" (\n\t  SET DOWNLOAD_URL=\"%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar\"\n\t)\n    echo Couldn't find %WRAPPER_JAR%, downloading it ...\n\techo Downloading from: %DOWNLOAD_URL%\n\t\n    powershell -Command \"&{\"^\n\t\t\"$webclient = new-object System.Net.WebClient;\"^\n\t\t\"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {\"^\n\t\t\"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');\"^\n\t\t\"}\"^\n\t\t\"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')\"^\n\t\t\"}\"\n    echo Finished downloading %WRAPPER_JAR%\n)\n@REM End of extension\n\n%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% \"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%\" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*\nif ERRORLEVEL 1 goto error\ngoto end\n\n:error\nset ERROR_CODE=1\n\n:end\n@endlocal & set ERROR_CODE=%ERROR_CODE%\n\nif not \"%MAVEN_SKIP_RC%\" == \"\" goto skipRcPost\n@REM check for post script, once with legacy .bat ending and once with .cmd ending\nif exist \"%HOME%\\mavenrc_post.bat\" call \"%HOME%\\mavenrc_post.bat\"\nif exist \"%HOME%\\mavenrc_post.cmd\" call \"%HOME%\\mavenrc_post.cmd\"\n:skipRcPost\n\n@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'\nif \"%MAVEN_BATCH_PAUSE%\" == \"on\" pause\n\nif \"%MAVEN_TERMINATE_CMD%\" == \"on\" exit %ERROR_CODE%\n\nexit /B %ERROR_CODE%\n"
  },
  {
    "path": "pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>com.mark</groupId>\n    <artifactId>JavaBasic</artifactId>\n    <version>0.0.1-SNAPSHOT</version>\n    <packaging>jar</packaging>\n\n    <name>JavaBasic</name>\n    <url>http://maven.apache.org</url>\n\n    <properties>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <java.version>1.8</java.version>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <groupId>junit</groupId>\n            <artifactId>junit</artifactId>\n            <version>4.13.1</version>\n            <scope>test</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>commons-io</groupId>\n            <artifactId>commons-io</artifactId>\n            <version>2.7</version>\n        </dependency>\n\n        <!-- MaxMind -->\n        <dependency>\n            <groupId>com.maxmind.geoip2</groupId>\n            <artifactId>geoip2</artifactId>\n            <version>2.12.0</version>\n        </dependency>\n\n        <dependency>\n            <groupId>com.alibaba</groupId>\n            <artifactId>fastjson</artifactId>\n            <version>1.2.83</version>\n        </dependency>\n\n        <dependency>\n            <groupId>io.azam.ulidj</groupId>\n            <artifactId>ulidj</artifactId>\n            <version>1.0.0</version>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>3.1</version>\n                <configuration>\n                    <source>1.8</source>\n                    <target>1.8</target>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "src/main/java/com/annotation/README.md",
    "content": "# 按运行机制分类\n- 源码注解：注解只在源码中存在，编译成.class文件就不存在了\n- 编译时注解：在源码和.class文件中都会存在注解\n- 运行时注解：在运行阶段还起作用，甚至韵影像运行逻辑的注解\n\n# 按来源分类\n- JDK 中自带的注解\n- 第三方的注解\n- 我们自定义注解\n\n# 自定义注解\n- 自定义注解语法要求\n- 注解的注解（元注解）\n- 使用自定义注解\n- 解析注解\n\n```\npackage com.sun.org.glassfish.gmbal;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Documented\n@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Description { //使用 @interface 来定义注解\n    String value(); // 成员以无参无异常方式声明\n\n    String key() default \"\"; 可以使用 default 为成员指定一个默认值\n}\n```\n> 成员的类型是受限制的，合法的类型包括Java基本类型及 String, Class, Annotation, Enumeration\n> \n> 如果注解只有一个成员，则成员名必须取名为value(), 在使用时可以忽略成员名和赋值号(=)\n>\n> 注解类可以没有成员，没有成员的注解可以被称为标识注解\n\n## 元注解\n```\n// 作用范围\npublic enum ElementType {\n    /** Class, interface (including annotation type), or enum declaration */\n    TYPE,\n\n    /** Field declaration (includes enum constants) */\n    FIELD,\n\n    /** Method declaration */\n    METHOD,\n\n    /** Formal parameter declaration */\n    PARAMETER,\n\n    /** Constructor declaration */\n    CONSTRUCTOR,\n\n    /** Local variable declaration */\n    LOCAL_VARIABLE,\n\n    /** Annotation type declaration */\n    ANNOTATION_TYPE,\n\n    /** Package declaration */\n    PACKAGE,\n\n    /**\n     * Type parameter declaration\n     *\n     * @since 1.8\n     */\n    TYPE_PARAMETER,\n\n    /**\n     * Use of a type\n     *\n     * @since 1.8\n     */\n    TYPE_USE\n}\n```\n```\n// Retention n. 保留；保持；维持；记忆力\n// 生命周期\npublic enum RetentionPolicy {\n    /**\n     * Annotations are to be discarded by the compiler.\n     */\n    SOURCE,\n\n    /**\n     * Annotations are to be recorded in the class file by the compiler\n     * but need not be retained by the VM at run time.  This is the default\n     * behavior.\n     */\n    CLASS,\n\n    /**\n     * Annotations are to be recorded in the class file by the compiler and\n     * retained by the VM at run time, so they may be read reflectively.\n     *\n     * @see java.lang.reflect.AnnotatedElement\n     */\n    RUNTIME\n}\n```\n\n```\n@Documented\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.ANNOTATION_TYPE)\npublic @interface Inherited {\n}\n\n@Documented\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.ANNOTATION_TYPE)\npublic @interface Documented {\n}\n```\n\n## 自定义注解使用\n```\npackage com.annotation.own;\n\nimport java.lang.annotation.*;\n\n@Target({ElementType.METHOD, ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Inherited // 类之间继承上，接口实现不算\n@Documented\npublic @interface Description {\n\n    String value();\n\n    String desc();\n\n    String author();\n\n    int age() default 18;\n}\n```\n\n# 解析注解\n- 通过**反射**获取类，函数或成员上的运行时注解信息，从而实现动态控制程序运行逻辑\n\n# 项目实战 见 project 包中\n- 项目取自一个公司的持久层框架，用来代替Hibernete的解决方案，核心代码通过注解来实现\n- 需求\n    - 有一张用户表，字段用户id, 用户名, 昵称, 年龄, 性别, 所在城市, 邮箱, 手机号\n    - 方便对每个字段或字段组合条件进行检索，并打印出SQL\n    - 使用方式足够简单，见代码实例\n    - 可以看看 mybatis-plus 的源代码"
  },
  {
    "path": "src/main/java/com/annotation/jdk/Child.java",
    "content": "package com.annotation.jdk;\n\nimport com.annotation.own.Description;\n\n/**\n * @Override 这个注解 告诉编译器 / 程序员，方法覆盖接口中方法\n * Indicates that a method declaration is intended to override a method declaration in a supertype.\n * If a method is annotated with this annotation type compilers are required to generate an error\n * message unless at least one of the following conditions hold:\n *\n * The method does override or implement a method declared in a supertype.\n * The method has a signature that is override-equivalent to that of any public method declared in Object.\n */\n@Description(\"I am a class annotation.\")\npublic class Child implements Person {\n\n    @Override\n    @Description(\"I am a method annotation.\")\n    public String name() {\n        return null;\n    }\n\n    @Override\n    public int age() {\n        return 0;\n    }\n\n    @Override\n    public void sing() {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/jdk/ParseAnnotation.java",
    "content": "package com.annotation.jdk;\n\nimport com.annotation.own.Description;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\n\npublic class ParseAnnotation {\n    public static void main(String[] args) {\n        // 1. 使用类加载器加载类\n        try {\n            Class c = Class.forName(\"com.annotation.jdk.Child\");\n\n            // 2. 找到类上的注解\n            boolean flag = c.isAnnotationPresent(Description.class);\n            if (flag) {\n                // 3. 拿到注解实例\n                Description description = (Description) c.getAnnotation(Description.class);\n                System.out.println(description.value());\n            }\n\n            // 4. 找到方法上的注解\n            Method[] ms = c.getMethods();\n            for (Method m : ms) {\n                boolean annotationPresent = m.isAnnotationPresent(Description.class);\n                if (annotationPresent) {\n                    Description description = m.getAnnotation(Description.class);\n                    System.out.println(description.value());\n                }\n            }\n\n            // 5. 另一种解析方法\n            for (Method m : ms) {\n                Annotation[] as = m.getAnnotations();\n                for (Annotation a : as) {\n                    if (a instanceof Description) {\n                        Description description = (Description) a;\n                        System.out.println(description.value());\n                    }\n                }\n            }\n        } catch (ClassNotFoundException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/annotation/jdk/Person.java",
    "content": "package com.annotation.jdk;\n\n/**\n * Java 注解从 Java 5开始\n * @Deprecated 已过时；被废弃\n * A program element annotated @Deprecated is one that programmers are discouraged from using,\n * typically because it is dangerous, or because a better alternative exists. Compilers warn\n * when a deprecated program element is used or overridden in non-deprecated code.\n */\npublic interface Person {\n\n    public String name();\n\n    public int age();\n\n    @Deprecated\n    public void sing();\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/jdk/Test.java",
    "content": "package com.annotation.jdk;\n\n/**\n * @SuppressWarnings suppress v. 抑制，压制，阻止\n * Indicates that the named compiler warnings should be suppressed in the annotated element\n * (and in all program elements contained in the annotated element). Note that the set of warnings\n * suppressed in a given element is a superset of the warnings suppressed in all containing elements.\n * For example, if you annotate a class to suppress one warning and annotate a method to suppress another,\n * both warnings will be suppressed in the method.\n *\n * As a matter of style, programmers should always use this annotation on the most deeply nested element\n * where it is effective. If you want to suppress a warning in a particular method, you should annotate\n * that method rather than its class.\n */\npublic class Test {\n    @SuppressWarnings(\"deprecation\")\n    public void sing(String[] args) {\n        Person p = new Child();\n        p.sing();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/own/Description.java",
    "content": "package com.annotation.own;\n\nimport java.lang.annotation.*;\n\n@Target({ElementType.METHOD, ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@Inherited\n@Documented\npublic @interface Description {\n\n    String value() default \"\";\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/project/Column.java",
    "content": "package com.annotation.project;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Target(ElementType.FIELD)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Column {\n    String value();\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/project/Department.java",
    "content": "package com.annotation.project;\n\n@Table(\"t_department\")\npublic class Department {\n    @Column(\"id\")\n    private int id;\n    @Column(\"name\")\n    private String name;\n    @Column(\"leader\")\n    private String leader;\n    @Column(\"amount\")\n    private int amount;\n\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getLeader() {\n        return leader;\n    }\n\n    public void setLeader(String leader) {\n        this.leader = leader;\n    }\n\n    public int getAmount() {\n        return amount;\n    }\n\n    public void setAmout(int amount) {\n        this.amount = amount;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/project/Table.java",
    "content": "package com.annotation.project;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface Table {\n    String value();\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/project/Test.java",
    "content": "package com.annotation.project;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\n\npublic class Test {\n    public static void main(String[] args) {\n        User u1 = new User();\n        u1.setId(10); // 查询 id 为10的用户\n\n        User u2 = new User();\n        u2.setUserName(\"lucy\"); // 模糊查询用户名为 lucy 的用户\n\n        User u3 = new User();\n        u2.setEmail(\"mark@gmail.com,puma@163.com\"); // 查询任意一个邮箱\n\n        String sql1 = query(u1);\n        String sql2 = query(u2);\n        String sql3 = query(u3);\n        \n        System.out.println(sql1);\n        System.out.println(sql2);\n        System.out.println(sql3);\n\n        Department d = new Department();\n        d.setId(10);\n        d.setLeader(\"张三丰\");\n        \n        System.out.println(query(d));\n    }\n\n    private static String query(Object u) {\n        StringBuilder sb = new StringBuilder();\n        // 1. 获取 class\n        Class c = u.getClass();\n        // 2. 获取 table 名字\n        boolean exist = c.isAnnotationPresent(Table.class);\n        if (!exist) {\n            return null;\n        }\n        Table table = (Table) c.getAnnotation(Table.class);\n        String tableName = table.value();\n        sb.append(\"SELECT * FROM \").append(tableName).append(\" WHERE 1=1\");\n        // 遍历所有的字段\n        Field[] declaredFields = c.getDeclaredFields();\n        for (Field f : declaredFields) {\n            // 处理字段对应的 SQL\n            // 拿到字段的名字\n            boolean annotationPresent = f.isAnnotationPresent(Column.class);\n            if (!annotationPresent) {\n                continue;\n            }\n            Column column = f.getAnnotation(Column.class);\n            String columnName = column.value();\n            // 拿到字段的值\n            String fieldName = f.getName();\n            String method = \"get\" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);\n            Object fieldValue = null;\n            try {\n                Method invokeMethod = c.getMethod(method);\n                fieldValue = invokeMethod.invoke(u);\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n            // 拼装 SQL\n            if (fieldValue == null || (fieldValue instanceof Integer && (int) fieldValue == 0)) {\n                continue;\n            }\n            sb.append(\" AND \").append(fieldName);\n            if (fieldValue instanceof String) {\n                if (((String) fieldValue).contains(\",\")) {\n                    String[] strings = ((String) fieldValue).split(\",\");\n                    sb.append(\" IN (\");\n//                    int count = 0; // counter\n//                    for (String s : strings) {\n//                        ++ count;\n//                        sb.append(\"'\").append(s).append(\"'\");\n//                        if (count == strings.length) {\n//                            sb.append(\")\");\n//                        } else {\n//                            sb.append(\",\");\n//                        }\n//                    }\n\n                    for (String s : strings) {\n                        sb.append(\"'\").append(s).append(\"'\").append(\",\");\n                    }\n                    sb.deleteCharAt(sb.length() - 1);\n                    sb.append(\")\");\n                } else {\n                    sb.append(\"=\").append(\"'\").append(fieldValue).append(\"'\");\n                }\n            } else if (fieldValue instanceof Integer) {\n                sb.append(\"=\").append(fieldValue);\n            }\n\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/annotation/project/User.java",
    "content": "package com.annotation.project;\n\n@Table(\"t_user\")\npublic class User {\n\n    @Column(\"id\")\n    private int id;\n    @Column(\"user_name\")\n    private String userName;\n    @Column(\"nick_name\")\n    private String nickName;\n    @Column(\"age\")\n    private int age;\n    @Column(\"city\")\n    private String city;\n    @Column(\"email\")\n    private String email;\n    @Column(\"mobile\")\n    private String mobile;\n\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getUserName() {\n        return userName;\n    }\n\n    public void setUserName(String userName) {\n        this.userName = userName;\n    }\n\n    public String getNickName() {\n        return nickName;\n    }\n\n    public void setNickName(String nickName) {\n        this.nickName = nickName;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n    public String getCity() {\n        return city;\n    }\n\n    public void setCity(String city) {\n        this.city = city;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n    public String getMobile() {\n        return mobile;\n    }\n\n    public void setMobile(String mobile) {\n        this.mobile = mobile;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch01/ConcurrencyTest.java",
    "content": "package com.art.concurrency.ch01;\n\n/**\n * 1. 循环次数\n * 2. 串并行程序实行时间\n * 3. Lmbench3 http://www.bitmover.com/lmbench/ 上下文切换的时长\n * 4. vmstat 上下文切换的次数\n * 5. 如何减少上下文切换\n *  无锁并发编程， CAS算法， 使用最少线程， 使用协程\n *  无锁并发编程：不同线程处理不同段的数据\n */\npublic class ConcurrencyTest {\n    private static final long count = 100001;\n\n    public static void main(String[] args) throws InterruptedException {\n        concurrency();\n        serial();\n    }\n\n    private static void serial() {\n        long start = System.currentTimeMillis();\n        int a = 0;\n        for (long i = 0; i < count; i++) {\n            a += 5;\n        }\n        int b = 0;\n        for (long i = 0; i < count; i++) {\n            b--;\n        }\n        long time = System.currentTimeMillis() - start;\n        System.out.println(\"serial: \" + time);\n    }\n\n    private static void concurrency() throws InterruptedException {\n        long start = System.currentTimeMillis();\n        Thread thread = new Thread(new Runnable() {\n            @Override\n            public void run() {\n                int a = 0;\n                for (long i = 0; i < count; i++) {\n                    a += 5;\n                }\n            }\n        });\n        thread.start();\n\n        int b = 0;\n        for (long i = 0; i < count; i++) {\n            b--;\n        }\n        long time = System.currentTimeMillis() - start;\n        thread.join();\n        System.out.println(\"concurrency: \" + time);\n    }\n\n}"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch01/DeadLockDemo.java",
    "content": "package com.art.concurrency.ch01;\n\npublic class DeadLockDemo {\n    private static String A = \"A\";\n    private static String B = \"B\";\n\n    public static void main(String[] args) {\n        new DeadLockDemo().deadLock();\n    }\n\n    private void deadLock() {\n        Thread t1 = new Thread(new Runnable() {\n            @Override\n            public void run() {\n                synchronized (A) {\n                    try {\n                        Thread.sleep(2000);\n                    } catch (InterruptedException e) {\n                        e.printStackTrace();\n                    }\n                    synchronized (B) {\n                        System.out.println(\"1\");\n                    }\n                }\n            }\n        });\n\n        Thread t2 = new Thread(new Runnable() {\n            @Override\n            public void run() {\n                synchronized (B) {\n                    try {\n                        Thread.sleep(9000);\n                    } catch (InterruptedException e) {\n                        e.printStackTrace();\n                    }\n                    synchronized (A) {\n                        System.out.println(\"2\");\n                    }\n                }\n            }\n        });\n        t1.start();\n        t2.start();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch04/Daemon.java",
    "content": "package com.art.concurrency.ch04;\n\nimport com.art.concurrency.utils.SleepUtils;\n\npublic class Daemon {\n    public static void main(String[] args) {\n        Thread thread = new Thread(new DaemonRunner(), \"DaemonRunner\");\n        thread.setDaemon(Boolean.TRUE);\n        thread.start();\n    }\n\n    static class DaemonRunner implements Runnable {\n\n        @Override\n        public void run() {\n            SleepUtils.second(10);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch04/Deprecated.java",
    "content": "package com.art.concurrency.ch04;\n\nimport com.art.concurrency.utils.SleepUtils;\n\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.concurrent.TimeUnit;\n\npublic class Deprecated {\n    public static void main(String[] args) throws InterruptedException {\n        DateFormat format = new SimpleDateFormat(\"HH:mm:ss\");\n        Thread printThread = new Thread(new Runner(), \"printThread\");\n        printThread.setDaemon(true);\n        printThread.start();\n        TimeUnit.SECONDS.sleep(3);\n\n        printThread.suspend(); // 线程暂停\n        System.out.println(\"main suspend PrintThread at \" + format.format(new Date()));\n        TimeUnit.SECONDS.sleep(3);\n\n        printThread.resume(); // 线程恢复\n        System.out.println(\"main resume PrintThread at \" + format.format(new Date()));\n        TimeUnit.SECONDS.sleep(3);\n\n        printThread.stop(); // 线程停止\n        System.out.println(\"main stop PrintThread at \" + format.format(new Date()));\n        TimeUnit.SECONDS.sleep(3);\n    }\n    \n    static class Runner implements Runnable {\n        @Override\n        public void run() {\n            DateFormat format = new SimpleDateFormat(\"HH:mm:ss\");\n            while (true) {\n                System.out.println(Thread.currentThread().getName() + \" Run at \" + format.format(new Date()));\n                SleepUtils.second(1);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch04/Interrupted.java",
    "content": "package com.art.concurrency.ch04;\n\nimport com.art.concurrency.utils.SleepUtils;\n\nimport java.util.concurrent.TimeUnit;\n\npublic class Interrupted {\n    public static void main(String[] args) throws InterruptedException {\n        Thread sleepRunner = new Thread(new SleepRunner(), \"SleepRunner\");\n        sleepRunner.setDaemon(true);\n\n        Thread busyRunner = new Thread(new BusyRunner(), \"BusyRunner\");\n        busyRunner.setDaemon(true);\n\n        sleepRunner.start();\n        busyRunner.start();\n\n        TimeUnit.SECONDS.sleep(5);\n        sleepRunner.interrupt();\n        busyRunner.interrupt();\n\n        System.out.println(\"SleepThread interrupted is \" + sleepRunner.isInterrupted());\n        System.out.println(\"BusyThread interrupted is \" + busyRunner.isInterrupted());\n\n        SleepUtils.second(2);\n    }\n\n    static class SleepRunner implements Runnable {\n        @Override\n        public void run() {\n            while (true) {\n                SleepUtils.second(10);\n            }\n        }\n    }\n\n    static class BusyRunner implements Runnable {\n        @Override\n        public void run() {\n            while (true) {\n\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch04/MultiThread.java",
    "content": "package com.art.concurrency.ch04;\n\nimport java.lang.management.ManagementFactory;\nimport java.lang.management.ThreadInfo;\nimport java.lang.management.ThreadMXBean;\n\npublic class MultiThread {\n    public static void main(String[] args) {\n        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();\n        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);\n        for (ThreadInfo threadInfo : threadInfos) {\n            System.out.println(\"[\" + threadInfo.getThreadId() + \"] \" + threadInfo.getThreadName());\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch04/Priority.java",
    "content": "package com.art.concurrency.ch04;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class Priority {\n    private static volatile boolean notStart = true;\n    private static volatile boolean notEnd = true;\n\n    public static void main(String[] args) throws InterruptedException {\n        List<Job> jobs = new ArrayList<>();\n        for (int i = 0; i < 10; i++) {\n            int priority = i < 5 ? Thread.MIN_PRIORITY : Thread.MAX_PRIORITY;\n            Job job = new Job(priority);\n            jobs.add(job);\n            Thread thread = new Thread(job, \"thread:\" + i);\n            thread.setPriority(priority);\n            thread.start();\n        }\n        notStart = false;\n        TimeUnit.SECONDS.sleep(10);\n        notEnd = false;\n\n        for (Job job : jobs) {\n            System.out.println(\"Job Priority:\" + job.priority + \", Count : \" + job.jobCount);\n        }\n    }\n\n    static class Job implements Runnable {\n        private int priority;\n        private long jobCount;\n\n        public Job() {\n        }\n\n        public Job(int priority) {\n            this.priority = priority;\n        }\n\n        public Job(int priority, long jobCount) {\n            this(priority);\n            this.jobCount = jobCount;\n        }\n\n        @Override\n        public void run() {\n            while (notStart) {\n                Thread.yield();\n            }\n            while (notEnd) {\n                Thread.yield();\n                jobCount++;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch04/Shutdown.java",
    "content": "package com.art.concurrency.ch04;\n\nimport java.util.concurrent.TimeUnit;\n\npublic class Shutdown {\n    public static void main(String[] args) throws InterruptedException {\n        Runner one = new Runner();\n        Thread countThead = new Thread(one, \"CountThread\");\n        countThead.start();\n\n        TimeUnit.SECONDS.sleep(1);\n        countThead.interrupt();\n\n        Runner two = new Runner();\n        countThead = new Thread(two, \"CountThread\");\n        countThead.start();\n        TimeUnit.SECONDS.sleep(1);\n        two.cancel();\n    }\n    \n    static class Runner implements Runnable {\n        private long i;\n        private volatile boolean on = true;\n        \n        @Override\n        public void run() {\n            while (on && !Thread.currentThread().isInterrupted()) {\n                i ++;\n            }\n            System.out.println(\"Count i = \" + i);\n        }\n\n        public void cancel() {\n            on = false;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch04/ThreadState.java",
    "content": "package com.art.concurrency.ch04;\n\nimport com.art.concurrency.utils.SleepUtils;\n\n/**\n * https://docs.oracle.com/javase/8/docs/api/index.html\n */\npublic class ThreadState {\n    public static void main(String[] args) {\n        Thread.State[] values = Thread.State.values();\n        System.out.println(values);\n\n        new Thread(new TimeWaiting(), \"TimeWaitingThread\").start();\n        new Thread(new Waiting(), \"WaitingThread\").start();\n\n        new Thread(new Blocked(), \"BlockedThread-1\").start();\n        new Thread(new Blocked(), \"BlockedThread-2\").start();\n    }\n\n    static class TimeWaiting implements Runnable {\n\n        @Override\n        public void run() {\n            SleepUtils.second(100);\n        }\n    }\n\n    static class Waiting implements Runnable {\n\n        @Override\n        public void run() {\n            while (true) {\n                synchronized (Waiting.class) {\n                    try {\n                        Waiting.class.wait();\n                    } catch (InterruptedException e) {\n                        e.printStackTrace();\n                    }\n                }\n            }\n        }\n    }\n\n    static class Blocked implements Runnable {\n\n        @Override\n        public void run() {\n            synchronized (Blocked.class) {\n                while (true) {\n                    SleepUtils.second(100);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch08/BankWaterService.java",
    "content": "package com.art.concurrency.ch08;\n\nimport java.util.Map;\nimport java.util.concurrent.*;\n\npublic class BankWaterService implements Runnable {\n\n    /**\n     * 创建四个屏障，处理完之后执行当前类的run方法\n     */\n    private CyclicBarrier cyclicBarrier = new CyclicBarrier(4, this);\n\n    /**\n     * 假设只有四个 sheet 页，所以启动 4 个线程\n     */\n    private Executor executor = Executors.newFixedThreadPool(4);\n\n    /**\n     * 保存每个 sheet 计算出的银行流水结果\n     */\n    private ConcurrentHashMap<String, Integer> sheetBankWaterCount = new ConcurrentHashMap<>();\n\n    private void count() {\n        for (int i = 0; i < 4; i++) {\n            executor.execute(new Runnable() {\n                @Override\n                public void run() {\n                    // 计算当前 sheet 的银流数据\n                    sheetBankWaterCount.put(Thread.currentThread().getName(), 1);\n                    try {\n                        // 计算完成，插入一个屏障\n                        cyclicBarrier.await();\n                    } catch (InterruptedException e) {\n                        e.printStackTrace();\n                    } catch (BrokenBarrierException e) {\n                        e.printStackTrace();\n                    }\n                }\n            });\n        }\n    }\n\n    @Override\n    public void run() {\n        int result = 0;\n        // 汇总每个 sheet 计算出来的结果\n        for (Map.Entry<String, Integer> sheet : sheetBankWaterCount.entrySet()) {\n            result += sheet.getValue();\n        }\n        // output\n        sheetBankWaterCount.put(\"result\", result);\n        System.out.println(result);\n    }\n\n    public static void main(String[] args) {\n        BankWaterService bankWaterService = new BankWaterService();\n        bankWaterService.count();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch08/CountDownLatchTest.java",
    "content": "package com.art.concurrency.ch08;\n\nimport java.util.concurrent.CountDownLatch;\n\npublic class CountDownLatchTest {\n    // 10 个线程\n    static CountDownLatch countDownLatch = new CountDownLatch(10);\n\n    public static void main(String[] args) throws InterruptedException {\n        for (int i = 0; i < 10; i++) {\n            int threadNo = i;\n            new Thread(new Runnable() {\n                @Override\n                public void run() {\n                    System.out.println(\"thread: \" + threadNo);\n                    // 执行完打印语句之后，count 数减一\n                    countDownLatch.countDown();\n                }\n            }).start();\n        }\n\n        // 当 count 为0时，就可以执行以后的打印语句\n        countDownLatch.await();\n\n        System.out.println(\"all threads finished.\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch08/CyclicBarrierTest.java",
    "content": "package com.art.concurrency.ch08;\n\nimport java.util.concurrent.BrokenBarrierException;\nimport java.util.concurrent.CyclicBarrier;\n\n/**\n * CyclicBarrier 可用于多线程计算数据，最后合并计算结果的场景。\n */\npublic class CyclicBarrierTest {\n    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);\n\n    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {\n        new Thread(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    cyclicBarrier.await();\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                } catch (BrokenBarrierException e) {\n                    e.printStackTrace();\n                }\n                System.out.println(1);\n            }\n        }).start();\n\n        cyclicBarrier.await();\n        System.out.println(2);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch08/CyclicBarrierTest02.java",
    "content": "package com.art.concurrency.ch08;\n\nimport java.util.concurrent.BrokenBarrierException;\nimport java.util.concurrent.CyclicBarrier;\n\npublic class CyclicBarrierTest02 {\n    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new A());\n\n    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {\n        new Thread(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    cyclicBarrier.await();\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                } catch (BrokenBarrierException e) {\n                    e.printStackTrace();\n                }\n                System.out.println(1);\n            }\n        }).start();\n\n        cyclicBarrier.await();\n        System.out.println(2);\n    }\n    \n    static class A implements Runnable {\n\n        @Override\n        public void run() {\n            System.out.println(3);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch08/CyclicBarrierTest03.java",
    "content": "package com.art.concurrency.ch08;\n\nimport java.util.concurrent.BrokenBarrierException;\nimport java.util.concurrent.CyclicBarrier;\n\npublic class CyclicBarrierTest03 {\n    static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);\n\n    public static void main(String[] args) {\n        Thread t = new Thread(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    cyclicBarrier.await();\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                } catch (BrokenBarrierException e) {\n                    e.printStackTrace();\n                }\n            }\n        });\n        t.start();\n        t.interrupt();\n        try {\n            cyclicBarrier.await();\n        } catch (Exception e) {\n            System.out.println(cyclicBarrier.isBroken());\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch08/ExchangerTest.java",
    "content": "package com.art.concurrency.ch08;\n\nimport java.util.concurrent.Exchanger;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\n\n/**\n * 用户遗传算法\n * 用于校对工作\n */\npublic class ExchangerTest {\n    private static final Exchanger<String> exgr = new Exchanger<>();\n    private static ExecutorService threadPool = Executors.newFixedThreadPool(2);\n\n    public static void main(String[] args) {\n        threadPool.execute(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    String a = \"银行流水A\";\n                    // 同步点，第一个线程执行exchange函数的时候，线程1会等待第二线程也执行 exchange 函数\n                    String msg = exgr.exchange(a);\n                    System.out.println(\"msg=\" + msg);\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                }\n            }\n        });\n\n        threadPool.execute(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    String b = \"银行流水B\";\n                    String a = exgr.exchange(b);\n                    System.out.println(\"a与b数据是否一致：\" + a.equals(b));\n                    System.out.println(\"A=\" + a);\n                    System.out.println(\"B=\" + b);\n                } catch (InterruptedException e) {\n                    e.printStackTrace();\n                }\n            }\n        });\n        threadPool.shutdown();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/ch08/SemaphoreTest.java",
    "content": "package com.art.concurrency.ch08;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Semaphore;\n\n/**\n * 可以用作流量控制，特别是公用资源有限的应用场景，如数据库连接。\n * 有一个需求，要读取几万个文件的数据，因为是IO密集型任务，我们可以启动几十个线程并发读取\n * 但是如果读到内存后，还需要存储到数据库中，而且数据库的连接的连接数只有10个，这时我们必\n * 须控制只有10个线程同时获取数据库连接保存数据，否则无法获取数据库连接。\n */\npublic class SemaphoreTest {\n    private static final int THREAD_COUNT = 30;\n\n    private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);\n\n    /**\n     * 最大并发数 10\n     */\n    private static Semaphore s = new Semaphore(10);\n\n    public static void main(String[] args) {\n        for (int i = 0; i < THREAD_COUNT; i++) {\n            threadPool.execute(new Runnable() {\n                @Override\n                public void run() {\n                    try {\n                        s.acquire();\n                        System.out.println(\"save data.\");\n                        s.release();\n                    } catch (InterruptedException e) {\n                        e.printStackTrace();\n                    }\n                }\n            });\n        }\n        threadPool.shutdown();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/art/concurrency/utils/SleepUtils.java",
    "content": "package com.art.concurrency.utils;\n\nimport java.util.concurrent.TimeUnit;\n\npublic class SleepUtils {\n    public static final void second(long seconds) {\n        try {\n            TimeUnit.SECONDS.sleep(seconds);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/BigDecimalTest.java",
    "content": "package com.basic.alibaba;\n\nimport java.math.BigDecimal;\n\n/**\n * @description alibaba\n * @author shenjy\n * @since 2019/08/04\n */\npublic class BigDecimalTest {\n    public static void main(String[] args) {\n        BigDecimal a = new BigDecimal(0.1);\n        System.out.println(a);\n\n        // 推荐使用\n        BigDecimal b = new BigDecimal(\"0.1\");\n        System.out.println(b);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/CollectionTest.java",
    "content": "package com.basic.alibaba;\n\n/**\n * 集合处理\n *\n * @author MarkShen1992\n * @since 20200509\n */\npublic class CollectionTest {\n    /*\n    public static void main(String[] args) {\n        List<String> strings = new ArrayList<>();\n\n        // 判断所有集合内部的元素是否为空，使用 isEmpty()方法\n        if (strings.isEmpty()) {\n            System.out.println(\"集合 strings 为空...\");\n        }\n\n        strings.add(\"1\");\n        strings.add(\"2\");\n        strings.add(\"3\");\n\n        List<String> strings1 = strings.subList(0, 2);\n        strings1.forEach(System.out::println);\n        // ArrayList 的 subList 结果不可强转成 ArrayList\n        // java.lang.ClassCastException: java.util.ArrayList$SubList cannot be cast to java.util.ArrayList\n        // ArrayList<String> arrayList = (ArrayList<String>) strings1;\n\n        // java.lang.UnsupportedOperationException, Returns an empty list (immutable).\n        List<Integer> ints = Collections.emptyList();\n        // ints.add(1);\n\n        List<Pair<String, Double>> pairArrayList = new ArrayList<>(3);\n        pairArrayList.add(new Pair<>(\"version\", 6.19));\n        pairArrayList.add(new Pair<>(\"version\", 10.24));\n\n        // 在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时，一定要注意当 value 为 null 时会抛 NPE 异常\n        // pairArrayList.add(new Pair<>(\"version\", null));\n        Map<String, Double> map = pairArrayList.stream().collect(\n        // 生成的 map 集合中只有一个键值对：{version=13.14}\n        Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v2));\n\n        List<String> list = new ArrayList<>(2);\n        list.add(\"guan\");\n        list.add(\"bao\");\n        String[] array = list.toArray(new String[0]);\n        int length = array.length;\n        System.out.println(length);\n\n        // 在使用 Collection 接口任何实现类的 addAll()方法时，都要对输入的集合参数进行 NPE 判断\n\n        //\n        Long[] longArr = new Long[] { 1L, 2L, 3L, 4L, 5L, 6L };\n        List<Long> longs = Arrays.asList(longArr);\n        // longs.add(7L);\n        longArr[0] = 11L;\n\n        // PECS(Producer Extends Consumer Super)原则\n        // https://itimetraveler.github.io/2016/12/27/%E3%80%90Java%E3%80%91%E6%B3%9B%E5%9E%8B%E4%B8%AD%20extends%20%E5%92%8C%20super%20%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%9F/\n\n        // 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator\n        // 方式，如果并发操作，需要对 Iterator 对象加锁。\n        List<String> list2 = new ArrayList<>();\n        list2.add(\"1\");\n        list2.add(\"2\");\n        Iterator<String> iterator = list2.iterator();\n        while (iterator.hasNext()) {\n            String item = iterator.next();\n            if (item.length() > 0) {\n                iterator.remove();\n            }\n        }\n    }\n    */\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/ConfusingName.java",
    "content": "package com.basic.alibaba;\n\n/**\n * @author MarkShen1992\n * @since 2020.4.29\n */\npublic class ConfusingName {\n    public int stock;\n    private boolean condition;\n\n    // 非 setter/getter 的参数名称，不允许与本类成员变量同名\n    public void get(String alibaba) {\n        if (condition) {\n            final int money = 666;\n        }\n        for (int i = 0; i < 10; i++) {\n            // 在同一方法体中，不允许与其它代码块中的 money 命名相同\n            final int money = 15978;\n        }\n    }\n}\n\nclass Son extends ConfusingName {\n    public int stock;\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/DateTest.java",
    "content": "package com.basic.alibaba;\n\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.time.LocalDate;\nimport java.util.Date;\n\n/**\n * 日期时间规约\n *\n * @author MarkShen1992\n * @since 20200508\n */\npublic class DateTest {\n\n    private final static String PATTERN = \"yyyy-MM-dd HH:mm:ss\";\n\n    /**\n     * 月\n     */\n    private final static int MONTH = 1;\n\n    /**\n     * 日\n     */\n    private final static int DAY = 1;\n\n    public static void main(String[] args) {\n        String time = \"2023-01-04T00:00:00\";\n        System.out.println(time.split(\"T\")[0].replace(\"-\", \"/\"));\n\n        DateFormat dateFormat = new SimpleDateFormat(PATTERN);\n        System.out.println(dateFormat.format(new Date()));\n\n        // 获取当前毫秒数\n        System.out.println(System.currentTimeMillis());\n        // 纳秒\n        System.out.println(System.nanoTime());\n\n        // 统计时间等场景\n        // Instant\n\n        // 获取今年的天数\n        int daysOfThisYear = LocalDate.now().lengthOfYear();\n        System.out.println(daysOfThisYear);\n\n        // 获取指定某年的天数\n        System.out.println(getDaysOfCurrentYear(2016));\n    }\n\n    private static int getDaysOfCurrentYear(int currentYear) {\n        return LocalDate.of(currentYear, MONTH, DAY).lengthOfYear();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/FloatPrimitiveTest.java",
    "content": "package com.basic.alibaba;\n\n/**\n * @description alibaba\n * @author shenjy\n * @since 2019/08/04\n */\npublic class FloatPrimitiveTest {\n    public static void main(String[] args) {\n        float a = 1.0f - 0.9f;\n        float b = 0.9f - 0.8f;\n        if (a == b) {\n            System.out.println(\"true\");\n        } else {\n            System.out.println(\"false\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/FloatWrapTest.java",
    "content": "package com.basic.alibaba;\n\n/**\n * @description alibaba\n * @author shenjy\n * @since 2019/08/04\n */\npublic class FloatWrapTest {\n    public static void main(String[] args) {\n        Float a = Float.valueOf(1.0f - 0.9f);\n        Float b = Float.valueOf(0.9f - 0.8f);\n        if (a == b) {\n            System.out.println(\"true\");\n        } else {\n            System.out.println(\"false\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/IntegerCacheTest.java",
    "content": "package com.basic.alibaba;\n\n/**\n * IntegerCacheTest\n *\n * @author MarkShen1992\n * @since 2020.5.1\n */\npublic class IntegerCacheTest {\n    public static void main(String[] args) {\n        Integer aa = 127;\n        Integer bb = 127;\n        System.out.println(aa.equals(bb));\n        System.out.println(aa == bb);\n\n        Integer a = 128;\n        Integer b = 128;\n        System.out.println(a == b);\n        System.out.println(a.equals(b));\n\n        int aaa = 128;\n        int bbb = 128;\n        System.out.println(aaa == bbb);\n\n        Integer c = null;\n        Boolean flag = false;\n        // a*b 的结果是 int 类型，那么 c 会强制拆箱成 int 类型，抛出 NPE 异常\n        Integer result = (flag ? a * b : c);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/LockTest.java",
    "content": "package com.basic.alibaba;\n\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * @description alibaba\n * @author shenjy\n * @since 2019/08/04\n */\npublic class LockTest {\n    private final static Lock lock = new ReentrantLock();\n\n    public static void main(String[] args) {\n        try {\n            lock.tryLock();\n        } catch (Exception e) {\n            e.printStackTrace();\n        } finally {\n            lock.unlock();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/PrimitiveTypeArrayMaxSizeTest.java",
    "content": "package com.basic.alibaba;\n\n/**\n * C:\\Users\\shenjy>java -version java version \"1.8.0_112\" Java(TM) SE Runtime Environment (build 1.8.0_112-b15) Java\n * HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)\n */\npublic class PrimitiveTypeArrayMaxSizeTest {\n    public static void main(String[] args) {\n        // JVM 学习站点：\n        // 1. http://lovestblog.cn/\n        // 2. https://opts.console.heapdump.cn/\n        // 3. https://heapdump.cn/\n\n        // 注意：这里使用的虚拟机参数：-Xms9g -Xmx9g\n        // Xms: 初始化时候堆大小\n        // Xmx: 程序运行时堆大小\n\n        // char[] chars = new char[Integer.MAX_VALUE - 2];\n        // System.out.println(chars.length);\n\n        // byte[] bytes = new byte[Integer.MAX_VALUE - 2];\n        // System.out.println(bytes.length);\n\n        // short[] shorts = new short[Integer.MAX_VALUE - 2];\n        // System.out.println(shorts.length);\n\n        // int[] ints = new int[Integer.MAX_VALUE - 715784195];\n        // System.out.println(ints.length);\n\n        // long[] longs = new long[Integer.MAX_VALUE - 1431633921];\n        // System.out.println(longs.length);\n\n        // float[] floats = new float[Integer.MAX_VALUE - 715784195];\n        // System.out.println(floats.length);\n\n        // double[] doubles = new double[Integer.MAX_VALUE - 1431633921];\n        // System.out.println(doubles.length);\n\n        boolean[] booleans = new boolean[Integer.MAX_VALUE - 2];\n        System.out.println(booleans.length);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/SwitchTest.java",
    "content": "package com.basic.alibaba;\n\n/**\n * @description alibaba\n * @author shenjy\n * @since 2019/08/04\n */\npublic class SwitchTest {\n    public static void main(String[] args) {\n        String param = null;\n        switch (param) {\n            case \"null\":\n                System.out.println(\"null\");\n                break;\n            default:\n                System.out.println(\"default\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/alibaba/package-info.java",
    "content": "package com.basic.alibaba;\n\n/**\n * @link https://developer.aliyun.com/special/tech-java\n * 优雅性，可扩展性，可读性\n * 分布式事务，分布式消息队列\n * 在POJO类里面，方法参数推荐使用包装数据类型，数值计算使用基本数据类型\n * 代码质量的度量指标：可读性，可扩展性，可维护性\n * 符合开发规范，最合适的地方用最恰当的类的最恰当的方法去处理业务，算法的复杂度，考虑算法的调用频率\n * p3c idea插件， eclipse插件\n *\n * 广度和深度\n * 首先拓宽自己的广度，然后选择自己擅长的领域去搞\n * 推荐读 JDK源码，熟读 API\n * Dubbo, RocketMQ => 高并发，高可用，分布式\n * 多写写原型，像Dubbo原型， RocketMQ原型等\n * 保持技术的敏感性，对代码的敏感性\n * 修改的代码越多，可扩展性越差\n *\n * (奉献式)热爱，(极致)卓越，思考(主动)\n */"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0100Introduction.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 简介\n * 读书怎么读：看一个大概，直接用，用的时候回来再查\n * JDK安装后，看下JDK安装目录\n * @author MarkShen1992\n * @since 20191101\n */\npublic class Chapter0100Introduction {\n    public static void main(String[] args) {\n        /**\n         * SCM系统\n         * 电信宽带运营平台\n         * 远程教学平台\n         * VOD\n         * 视频监控\n         * 可视电话\n         * ERP\n         * 视频会议\n         * 新闻发布系统\n         * 网上商城，电子商务\n         * 移动增值平台\n         */\n\n        /**\n         * 课程内容：\n         *      Java基础\n         *          语法基础\n         *          OO\n         *          Exception\n         *          Array\n         *          基础类\n         *          I/O stream\n         *          Collection/Generic\n         *          Thread\n         *          TCP/UDP\n         *          GUI\n         *          MetaData(EJB3.0)\n         *          RegExp\n         *          沟通的时候，当你说任何话的时候站在对方角度上考虑下，看他能不能接受\n         *          没事的时候，多看看数据结构的内容，算法，设计模式\n         *     数据库的知识\n         *     html，css, javascript, JSP, Servlet\n         *     框架选择，技术选型\n         *     Java Web开发框架\n         *     Hibernate, Mybatis, JPO(掌握原理，算法+数据结构)\n         *     学新东西是件好事儿\n         *     EJB3.0的课程，EJB2.0\n         *     在招聘网站搜索，招某些职位的量\n         *     铺网络，上应用\n         * 教学方法：\n         *      巨无霸式教学\n         *      理论\n         *      举例\n         *      理论回顾\n         *      联系\n         *      讲解\n         *      注重结合工程实践\n         *      注重传授自学能力\n         *\n         *      时间短，强度大，这个时候要背一些东西的时候还是要背些内容的\n         *\n         * 能力的三个层次：\n         *      1. 知识：（接受能力）\n         *          学习前人的东西\n         *      2. 解决问题的方法：（碰见什么问题，用什么方法）\n         *          灵活运用学到的东西\n         *      3. 解决问题的思路：（掌握解决问题的思路，拓展一条思路）\n         *          创造解决问题的方法\n         *      灵活一点儿，再灵活一点\n         *\n         * 学习方法；\n         *      看算法那本书\n         *      完成习题\n         *      运用自学的能力\n         *          读，写，查，背（*对底子比较薄的同学）\n         *\n         * 预备知识：\n         *      英语\n         *      计算机基本操作\n         *      正向的暗示\n         *      Google + 电驴\n         *      软件行业认证：\n         *          现在开始别听别人忽悠，别听任何人忽悠，别听我忽悠\n         *          用自己的脑子去认识这个世界\n         *\n         *          国外比较认软件认证：Oracle认证，CCIE(Cisco Certified Internetwork Expert)\n         *          考含金量比较高的认证\n         *          ERP咨询师\n         *          SAP咨询师\n         *          共享软件，everything\n         *          努力，勤奋\n         *          琢磨人，总是要多走一步；走一步看三步，随时留意一些细节\n         *          身体：\n         *              腰椎，颈椎，手腕\n         *\n         * 教学资源：\n         *\n         * 企业与学校之间的区别\n         *  时限\n         *  使用为主\n         *\n         * 知识分类：\n         *  实际开发过程中经常要用的知识（牢牢掌握）\n         *  不经常使用用时就可以查到（了解）\n         *  八辈子用不到的知识（运用自己的能里去查）\n         *\n         *  管理好自己的精力\n         *  乐观的努力\n         *  眼光要高远一点儿\n         *  脚步要踏实\n         *\n         *  问题（老师）\n         *  讲的多，练习时间少\n         *  只灌输知识点，没有串联\n         *  不培养自学能力\n         *  给答案不给思路\n         *  项目太简单\n         *  项目太复杂\n         *  项目太少\n         *  注重技巧，不重视基本功\n         *  种管理技巧，请开发技巧\n         *  知识太旧了\n         *\n         *  技术 + 行业知识\n         *  进销存系统\n         *\n         *  Java是解释型语言\n         *  分层思想\n         *\n         *  读书怎么读：看一个大概，直接用，用的时候回来再查\n         */\n        System.out.println(\"Hello world!\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0101Identifier.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 标识符\n * @author MarkShen1992\n * @since 20191101\n */\npublic class Chapter0101Identifier {\n    public static void main(String[] args) {\n        /**\n         * 各种变量，类名，方法名\n         *\n         * 标识符规则\n         * 标识符由字母，下划线，数字，美元符号组成\n         * 标识符由字母，下划线，美元符号开头\n         * Java标识符大小写敏感，长度无限制\n         *\n         * 起名字规则：\"见名知意\"，且不能与Java关键词冲突\n         **/\n        int result = 10 + 10;\n        System.out.println(\"hello world, \" + result);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0102JavaKeyWord.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 关键字\n * @author MarkShen1992\n * @since 20191101\n */\npublic class Chapter0102JavaKeyWord {\n    public static void main(String[] args) {\n        /**\n         * Java关键字见文章：\n         * https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html\n         */\n        System.out.println(\"keyword...\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0103ConstantAndVariable.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 常量与变量\n * @author MarkShen1992\n * @since 20191101\n */\npublic class Chapter0103ConstantAndVariable {\n    public static void main(String[] args) {\n        /**\n         * 从本质上讲，变量其实就是内存中的一小块区域，使用变量名来访问这块区域，\n         * 因此，每一个变量使用前必须要先声明（申请内存），然后进行赋值（填充内容），才可以使用。\n         * 不同数据类型所占内存空间不同。\n         */\n        int num = 123; // 所在位置，栈内存\n        double d = 3.14;\n        char ch = 'a';\n        boolean flag = true;\n        String str = \"Hello world!\";\n        // 不可变的变量，类似于C语言中的 const 修饰的量，与Java中的 final 对应\n        final int var = 10;\n        float PI = 3.14f;\n\n\n        // 下面注释掉的这句话会有编译错误\n        // var = 12;\n\n        /**\n         * 重点内容：******\n         * 程序的执行过程：《深入Java虚拟机》，可以找官方英文版\n         * .exe文件放到操作系统直接执行；.class放到JVM中执行\n         * 程序首先从硬盘加载（load）到内存区域中\n         * 然后，操作系统会找到加载到内存中程序的main方法\n         * 然后，执行过程中的内存管理\n         * 内存管理中，在程序运行的时候，内存分为4个部分，不同操作系统不同\n         * 分别是：堆，栈，代码区，方法区\n         * 堆(Heap)：Java代码new出来的东西\n         * 栈(Stack)：局部变量\n         * 代码区(Code segment)：存放代码\n         * 数据区(Data segment)：静态变量，字符串变量\n         */\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0104TestVar.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 敲程序方法：在看懂整个程序的意思后，背着把程序敲出来；\n * 或者有自己的理解后，自己组织程序结构完成程序。\n * @author MarkShen1992\n * @since 20191102\n */\npublic class Chapter0104TestVar {\n\t\n\tstatic int j;\n\t\n\tpublic void m() {\n\t\tint i = 0;\n\t\tSystem.out.println(i);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tint i = 0; \n\t\tSystem.out.println(i);\n\t\tSystem.out.println(j);\n\t\t\n\t\tboolean b = false;\n\t\tif(b) {\n\t\t\tint c = 0;\n\t\t\tSystem.out.println(\"b is true\");\n\t\t}\n\t\t\n\t\t// System.out.println(c);\n\t\t\n\t\tlong longNum1 = 8888888888888L;\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0104TestVar2.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 数据类型测试\n * @author MarkShen1992\n * @since 20191102\n */\npublic class Chapter0104TestVar2 {\n    public static void main(String[] args) {\n        boolean b = true;\n        int x, y = 9;\n        double d = 3.1415;\n        char c1, c2;\n        c1 = '\\u534e';\n        c2 = 'c';\n        x = 12;\n        System.out.println(\"b=\" + b);\n        System.out.println(\"x=\" + x + \",y=\" + y);\n        System.out.println(\"d=\" + d);\n        System.out.println(\"c1=\" + c1);\n        System.out.println(\"c2=\" + c2);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0104VariableType.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 变量分类\n * @author MarkShen1992\n * @since 20191101\n */\npublic class Chapter0104VariableType {\n\n    // 成员变量\n    static int a; // 成员变量如何初始化的？在什么时候初始化的？\n\n    public static void main(String[] args) {\n        /**\n         * 按被声明的位置划分：\n         * 成员变量：方法外部，类内部定义的变量\n         * 局部变量：方法或语句块内部定义的变量\n         * 注意：类外不能声明变量， 方法的参数叫做局部变量\n         *\n         * 按所属数据类型划分：\n         * 基本数据类型\n         * 引用类型\n         */\n        // 局部变量\n        int b = 10;\n        System.out.println(a);\n        System.out.println(b);\n        /**\n         * 变量作用域：在大括号里面声明的变量出了大括号之后就没有人认识它了\n         */\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0105DataType.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 数据类型\n * @author MarkShen1992\n * @since 20191102\n */\npublic class Chapter0105DataType {\n    public static void main(String[] args) {\n        /**\n         * 基本数据类型：\n         * 数值型：\n         *      整数类型：byte, short, int, long\n         *      浮点类型：float, double\n         * 字符型(文本)：char\n         *      Java里面采用Unicode编码，每个字符占两个字节，因而可使用十六进制编码形式表示。\n         *      XML中编码问题\n         *      每种不同的文字，在计算机中表示为010101...\n         *      每个字节8位\n         *      中文编码问题\n         *      Unicode一统江湖，统一了全世界所有编码\n         *      https://en.wikipedia.org/wiki/Unicode 需要科学上网\n         * 布尔型(逻辑)：boolean\n         *\n         * 内存大小，小格的布局\n         * Java各个整数类型有固定的表数范围和字段长度，其不受具体操作系统影响，可以在各个平台移植。\n         */\n\n        /**\n         * In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java\n         * programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per\n         * boolean element.\n         *                                                -- 《JVM官方文档》\n         */\n        boolean flag = true;\n        if (flag) {\n            System.out.println(\"flag is valid.\");\n        }\n\n        // 字符型, 占两个字节\n        char c = 'a';\n        System.out.println(c);\n\n        /**\n         * 数类型, 占用内存1个字节, 1byte\n         * Java语言整型常量的三种表示\n         * 十进制\n         * 八进制：编码算法中使用，012\n         * 十六进制\n         *\n         * Java语言整形常量默认为int类型\n         */\n        byte by = 123;\n        System.out.println(by);\n\n        // 2 bytes\n        short sh = 123;\n        System.out.println(sh);\n\n        // 4 bytes\n        int num = 123;\n        System.out.println(num);\n\n        // 8 bytes\n        long lon = 1234L;\n        System.out.println(lon);\n\n        /**\n         * 浮点类型：浮点数在计算机中的表示，浮点数是有一定的误差的\n         * float, double\n         * 浮点数默认为 double类型\n         */\n\n        // 8 bytes\n        double PI = 3.14;\n        System.out.println(PI);\n\n        // 4 bytes, 精度\n        float PI2 = 3.14f;\n        // float PI2 = 3.14F;\n        System.out.println(PI2);\n\n        /**\n         * 引用数据类型:\n         * 类(class)\n         * 接口(interface)\n         * 数组(array)\n         */\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0106BasicDataTypeConvertPrinciple.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 基本数据类型转换\n * @author MarkShen1992\n * @since 20191102\n */\npublic class Chapter0106BasicDataTypeConvertPrinciple {\n    public static void main(String[] args) {\n        /**\n         * 整形，浮点型，字符型的数据在混合运算中相互转换，原则如下：\n         * 1）容量小的数据类型自动转换为容量大的数据类型，数据类型按容量大小(表示的数的大小)排序:\n         *      byte, short, char -> int -> long -> float -> double\n         *      byte, short, char之间不会相互转换，他们三者在计算前要先转换为 int.\n         * 2）容量大的数据类型转换为容量小的数据类型时，要加上强制转换符，但可能造成\n         *    精度降低或溢出\n         * 3）有多种数据类型的数据进行混合运算时，系统首先自动将所有数据转换成容量最大\n         *    的那一种数据类型，然后再进行计算\n         * 4）实数类型默认为 double\n         * 5）证书类型默认为 int\n         */\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0106TestConvert.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 练习程序\n * @author MarkShen1992\n * @since 20191102\n */\npublic class Chapter0106TestConvert {\n    public static void main(String arg[]) {\n        int i1 = 123;\n        int i2 = 456;\n        double d1 = (i1 + i2) * 1.2;// 系统将转换double型进行运算\n        float f1 = (float) ((i1 + i2) * 1.2);// 需要加强制转换符号\n        byte b1 = 67;\n        byte b2 = 89;\n        byte b3 = (byte) (b1 + b2);// 系统将转换为 int 进行运算，然后再转换回来\n        System.out.println(b3);\n        double d2 = 1e200;\n        float f2 = (float) d2;// 产生溢出\n        System.out.println(f2);\n\n        float f3 = 1.23f;// 必须加f, 浮点数直接砍掉是不可以的\n        long l1 = 123;\n        long l2 = 30000000000L;// 必须加L\n        float f = l1 + l2 + f3;// 系统将转换float型计算\n        long l = (long) f;// 强制转换会舍去小数部分（非四舍五入）\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0106TestConvert2.java",
    "content": "package com.basic.chapter0100;\n\npublic class Chapter0106TestConvert2 {\n    public static void main(String[] args) {\n        int i = 1, j = 12;\n        float f1 = (float) 0.1;  //0.1f\n        float f2 = 123;\n        long l1 = 12345678, l2 = 8888888888L;\n        double d1 = 2e20, d2 = 124;\n        byte b1 = 1, b2 = 2, b3 = 127;\n        j = j + 10;\n        i = i / 10;\n        // i = i * 0.1;\n        i = (int) (i * 0.1);\n        char c1 = 'a', c2 = 125;\n        byte b = (byte) (b1 - b2);\n        char c = (char) (c1 + c2 - 1);\n        float f3 = f1 + f2;\n        float f4 = (float) (f1 + f2 * 0.1);\n        double d = d1 * i + j;\n        float f = (float) (d1 * 5 + d2);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0107TestIF.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * if 表达式\n * @author MarkShen1992\n * @since 20191103\n */\npublic class Chapter0107TestIF {\n    public static void main(String[] args) {\n        int i = 20;\n        if (i < 20) {\n            System.out.println(\"<20\");\n            System.out.println(\"<20\");\n        } else if (i < 40) {\n            System.out.println(\"<40\");\n        } else if (i < 60) {\n            System.out.println(\"<60\");\n        } else\n            // 当if...else...语句中只有一个语句，可以省略大括号，不推荐使用\n            System.out.println(\">=60\");\n        System.out.println(\">=60\");\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0108For.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * for语句, 计算1到 100这100个数之和\n * foreach语句打印\n * 分析算法时候，分析内存，找到规律。分析别人的算法，多分析别人的程序\n * 多读别人的程序，提炼一些好的算法，算法慢慢积累，多看看数学\n *\n * @author MarkShen1992\n * @since 20191103\n */\npublic class Chapter0108For {\n    public static void main(String[] args) {\n        long result = 0;\n        for (int i = 1; i <= 100; i ++) {\n            result += i;\n        }\n        System.out.println(\"result=\" + result);\n        foreachTest();\n        System.out.println(\"factorial = \" + factorialCompute(3));\n        System.out.println(factorialRecursion(3));\n    }\n\n    /**\n     * print the array elements\n     */\n    public static void foreachTest() {\n        int[] arr = {1, 2, 3, 4};\n        for (int number : arr) {\n            System.out.println(number);\n        }\n    }\n\n    /**\n     * 计算 factorial 的阶乘, 1! + 2! + 3! + ... + factorial!\n     *\n     * @param factorial\n     * @return\n     */\n    public static int factorialCompute(int factorial) {\n        // 好的编程习惯，要对传进来的参数进行判断\n        if (factorial <= 0) {\n            return 0;\n        }\n\n        // 最终的一结果\n        int result = 0;\n        // 临时变量存数\n        int tmpNum = 1;\n        for (int i = 1; i <= factorial; i++) {\n            tmpNum *= i;\n            result += tmpNum;\n        }\n        return result;\n    }\n\n    /**\n     * 递归实现阶乘\n     *\n     * @param factorial\n     * @return\n     */\n    public static int factorialRecursion(int factorial) {\n        if (factorial <= 0) {\n            return 0;\n        }\n\n        if (factorial == 1) {\n            return 1;\n        }\n        return factorial * factorialRecursion(-- factorial);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0109TestWhile.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * while\n * do...while\n *\n * @author MarkShen1992\n * @since 20191103\n */\npublic class Chapter0109TestWhile {\n    public static void main(String[] args) {\n        int i = 0;\n        while (i < 10) {\n            System.out.println(i);\n            i++;\n        }\n\n        i = 0;\n        do {\n            i++;\n            System.out.println(i);\n        } while (i < 10);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0110TestBreakAndContinue.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * break\n * continue\n *\n * @author MarkShen1992\n * @since 20191103\n */\npublic class Chapter0110TestBreakAndContinue {\n    public static void main(String[] args) {\n        breakTest();\n        continueTest();\n    }\n\n    private static void continueTest() {\n        for (int i = 0; i < 10; i ++) {\n            if (i == 6) continue;\n            System.out.println(i);\n        }\n    }\n\n    private static void breakTest() {\n        for (int i = 0; i < 10; i ++) {\n            if (i == 6) break;\n            System.out.println(i);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0111TestSwitch.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * switch\n * @author MarkShen1992\n * @since 20191103\n */\npublic class Chapter0111TestSwitch {\n\tpublic static void main(String[] args) {\n\t\tint i = 8;\n\t\tswitch(i) {\n\t\t\t// 多个case可以合并到一起\n\t\t\tcase 8 :\n\t\t\tcase 3 :\n\t\t\tcase 2 :\n\t\t\t\tSystem.out.println(\"C\");\n\t\t\t\tbreak;\n\t\t\tcase 9 :\n\t\t\t\tSystem.out.println(\"D\");\n\t\t\t\tbreak;\n\t\t\tdefault: // default 可以省略，但是不建议\n\t\t\t\tSystem.out.println(\"error\");\n\t\t}\n\n\t\t// JDK7 new feature 语法\n\t\tString condition = \"abc\";\n\t\tswitch(condition) {\n\t\t\tcase \"abcd\" :\n\t\t\t\tSystem.out.println(\"abcd\");\n\t\t\t\tbreak; // 不加break，会产生case穿透问题\n\t\t\tcase \"abc\" :\n\t\t\t\tSystem.out.println(\"abc\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tSystem.out.println(\"1234\");\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0112TestMethod.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * 方法: 增强程序的复用性\n *\n * @author MarkShen1992\n * @since 20191103\n */\npublic class Chapter0112TestMethod {\n    public static void main(String[] args) {\n        m();\n        m2(2);\n        m3('3', 4);\n        m4(4, 6);\n        int i = m4(4, 6);\n        System.out.println(i);\n    }\n\n    public static void m() {\n        // return;\n        System.out.println(\"ok\");\n        System.out.println(\"hello\");\n    }\n\n    public static void m2(int i) {\n        if (i > 3)\n            return;\n        System.out.println(i);\n    }\n\n    public static void m3(int i, int j) {\n        System.out.println(i + j);\n    }\n\n    public static int m4(int i, int j) {\n        return i > j ? i : j;\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0113TestMethod2.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * method\n * @author MarkShen1992\n * @since 20191103\n */\npublic class Chapter0113TestMethod2 {\n\n    public int max(int a, int b) {\n        return a > b ? a : b;\n    }\n\n    public int min(int a, int b) {\n        return a < b ? a : b;\n    }\n\n    public static void main(String[] args) {\n        Chapter0113TestMethod2 t = new Chapter0113TestMethod2();\n        System.out.println(\"Max = \" + t.max(3, 4));\n        System.out.println(\"Min = \" + t.min(3, 4));\n        // System.out.println(Max(3, 4));\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Chapter0114Fab.java",
    "content": "package com.basic.chapter0100;\n\npublic class Chapter0114Fab {\n    public static void main(String[] args) {\n        System.out.println(f(-9));\n    }\n\n    public static long f(int index) {\n        if (index < 1) {\n            System.out.println(\"invalid parameter!\");\n            return -1;\n        }\n\n        if (index == 1 || index == 2) {\n            return 1;\n        }\n\n        long f1 = 1L;\n        long f2 = 1L;\n        long f = 0;\n\n        for (int i = 0; i < index - 2; i++) {\n            f = f1 + f2;\n            f1 = f2;\n            f2 = f;\n        }\n        return f;\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Test01.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * PPT中未敲完的程序\n *\n * @author MarkShen\n * @since 20191207\n */\npublic class Test01 {\n    public static void main(String[] args) {\n        int i1 = 10, i2 = 20;\n        int i = i2 ++;\n        System.out.println(\"i=\" + i);\n        System.out.println(\"i2=\" + i2);\n        i = ++ i2;\n        System.out.println(\"i=\" + i);\n        System.out.println(\"i2=\" + i2);\n        i = -- i1;\n        System.out.println(\"i=\" + i);\n        System.out.println(\"i1=\" + i1);\n        i = i1 --;\n        System.out.println(\"i=\" + i);\n        System.out.println(\"i1=\" + i1);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0100/Test02.java",
    "content": "package com.basic.chapter0100;\n\n/**\n * PPT中未敲完的程序\n *\n * @author MarkShen\n * @since 20191207\n */\npublic class Test02 {\n    public static void main(String[] args) {\n        boolean a, b, c;\n        a = true;\n        b = false;\n        c = a & b;\n        System.out.println(\"c=\" + c);\n        c = a | b;\n        System.out.println(\"c=\" + c);\n        c = a ^ b;\n        System.out.println(\"c=\" + c);\n        c = !a;\n        System.out.println(\"c=\" + c);\n        c = a && b;\n        System.out.println(\"c=\" + c);\n        c = a || b;\n        System.out.println(\"c=\" + c);\n\n        int i = 1, j = 2;\n        boolean flag1 = (i > 3) && ((i + j) > 5);\n        boolean flag2 = (i < 2) && ((i + j) < 6);\n\n        // 三目运算符号\n        int score = 80;\n        String result = score > 60 ? \"及格\" : \"不及格\";\n        System.out.println(result);\n\n        // fab\n        System.out.println(f(3));\n    }\n\n    public static int f(int n) {\n        if (n == 1 || n == 2) {\n            return 1;\n        } else {\n            return f(n - 1) + f(n - 2);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0200Introduction.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * 简介\n * 指导性思想（极其重要）\n * 第一步：考虑问题域中有哪些类，哪些对象\n * 第二步：这些个类，这些个对象有哪些个属性\n * 第三步：考虑类与类之间的关系，定他们之间的方法\n *\n * 分析问题域方法\n * 类，成员变量（属性）：找名词\n * 方法（函数）：找动词\n *\n * 万事万物皆对象\n * 追求：\n *      重用，可扩展性(多态)，可维护性，面向组件（二进制级别抽象）的编程，WebService，SOA，COM\n *\n * @author MarkShen1992\n * @since 20191104\n */\npublic class Chapter0200Introduction {\n    public static void main(String[] args) {\n        /**\n         * 编程语言的发展\n         * 面向过程设计思想\n         *      一切以我为中心\n         *      我第一步要干什么；\n         *        第二步要干什么；\n         *        ......\n         *\n         * 面向对象设计思想\n         *      车 go(新疆)，车怎么去，我不知道，最合适的方法应该出现在最合适的类里面，\n         *      车最知道自己的内部结构。在程序内，不在分解一步一步的过程，而是在问题域\n         *      里应该有哪些个对象，对象里面应该有哪些属性（静），哪些方法（动），对象\n         *      与对象之间的关系。\n         *\n         * 对象和类的概念\n         *      类是抽象的：具有某些特征的东西。一类事物的抽象。静态的属性\n         *          瓶子能倒水\n         *      对象是具体的，对应着数据库中的一条记录\n         *\n         * 类之间的关系\n         *      依赖 < 关联（我这个方法的参数是你这个类的对象） < 聚合 < 组合\n         *      为 设计模式 打基础\n         *      继承：...是一种..., extends\n         *      聚合：整体与局部的关系，...是...的一部分。\n         *      组合：密不可分，...是...必不可少的一部分。\n         *      UML图\n         *      实现关系：implements\n         *      多态：\n         *          存在继承关系；\n         *          方法重写\n         *          父类引用指向子类对象\n         *\n         * 对象和引用\n         *      引用：Java语言中除基本类型之外的变量类型都称为引用类型。\n         *      Java堆内存中的对象是通过栈内存中的引用对其操作的\n         *      占两块儿内存，堆内存，栈内存\n         *\n         * Java类的定义\n         * 构造函数(析构函数)\n         *      public 类名() {}\n         *      new 一个东西的时候要调用的方法，叫做构造方法。\n         *      一旦你自己重写构造方法，那么Java 编译器将不会为这个类添加默认的构造方法\n         *      所以，我们在new对象的时候，我们要做到的就是把那个无参的构造方法\n         *      手动加上\n         *\n         * 对象的创建和使用\n         *      Object o = new Object();\n         *      o.equals(new Object);\n         *\n         * this 关键字\n         *      当前对象\n         *      this(String...) 对应的构造方法\n         *      this.methodName 本类方法\n         *\n         * super 关键字\n         *      调用父类的内容\n         *      super(String...) 对应父类构造函数\n         *      super.methodName 父类方法\n         *\n         * static 关键字\n         *      类变量\n         *      类方法\n         *\n         * package 关键字\n         *      解决类名冲突的问题\n         *      命名：公司域名倒过来，默认为default包\n         *      包对应文件系统中的文件夹\n         *      根据业务分包\n         *      根据功能分包\n         *      如果向让别的人用你的类，首先要先用 import 关键字将其引入\n         *\n         * import 关键字\n         *      引入别的类库\n         *\n         * 访问控制 public protected private 友好\n         * 对于成员变量如下表：\n         * 修饰符       类内部     同一个包     子类      任何地方\n         * public        Y           N          N          N\n         * default       Y           Y          N          N\n         * protected     Y           Y          Y          N\n         * public        Y           Y          Y          Y\n         *\n         * 对于类来说\n         *  public：任何地方都可以使用这个类\n         *  default\n         *\n         * 类的继承 extends\n         *      特别注意下 protected 关键字\n         *      双亲委派机制\n         *      子类对象包含父类对象\n         *\n         * 方法的重写 @Override\n         *      从父类继承\n         *      相同的函数名称\n         *      相同的参数列表\n         *      相同的方法返回值\n         *      重写方法的时候要去父类copy, 也可以使用工具生成\n         *      重写的方法不可以使用比被重写方法更严格的访问权限\n         *\n         * final 关键字\n         *      类似于C语言中的 const\n         *      在内存中的 数据 区\n         *      被 final 修饰的变量不能被修改\n         *          成员变量\n         *          局部变量 (形参)\n         *      final 的方法不能被重写\n         *      final 的类不能被继承\n         *\n         * Object 类\n         * https://docs.oracle.com/javase/8/docs/\n         *      Java 根基类\n         *      多看JavaAPI\n         *      toString() 方法\n         *      equals方法\n         *\n         * 对象转型\n         *      父类引用指向子类对象\n         *      一个基类的引用不可以访问其子类对象新加的成员（属性和方法）\n         *      可以使用 引用变量 instanceof 类名，来判断该引用类型变量所指向的对象是否\n         *      属于该类或该类的子类\n         *      子类的对象可以当作基类的对象来使用称上转型(upcasting),反之，称为下转型\n         *\n         *      扩展性比较好的例子：\n         *      当你建好这个建筑后，或者你写好这个程序之后，把主建筑建好了，将来要加一些\n         *      其他的功能，尽量不要去修改主结构，叫扩展性好\n         *      多看 经典建筑方面的书籍，比如巴黎圣母院的重新设计\n         *\n         *      亮了！巴黎圣母院的新塔尖设计方案\n         *      http://dy.163.com/v2/article/detail/EET5G1F70528UJ6I.html\n         *      https://zhuanlan.zhihu.com/p/77317713\n         *\n         * 多态\n         *      存在继承关系\n         *      方法重写\n         *      父类引用指向子类对象\n         *      实际中new的谁，就调用谁的方法，函数指针，动态绑定，核心中的核心\n         *\n         * 抽象类 Abstract\n         *      用 abstract 修饰的类为抽象类， 修饰的方法为 抽象方法\n         *      抽象方法没有必要实现\n         *\n         *      // 相当于 C ++ 中的纯虚函数\n         *      public abstract void method();\n         *      当一个类中有抽象方法的时候，那么这个类必须被声明为抽象类，抽象类\n         *      必须被继承，抽象方法必须被重写\n         *      抽象类不可以 new 出对象\n         *      抽象类只需声明，不需要实现\n         *\n         * 接口 interface implements\n         *      多个无关的类可以实现同一个接口\n         *      一个类可以实现多个无关的接口\n         *      与继承关系类似，接口与实现类之间存在多态性\n         *\n         *      接口是抽象方法和常量值的定义的集合，接口是一种特殊的抽象类，这种抽象类中\n         *      只包含常量和方法的定义，而没有变量和方法的实现。\n         *\n         *      public static final int id = 1;\n         *      为什么要定义成 public static final 吗？为了修正 c++ 中多继承时候，容易\n         *      出现问题的地方。c++ 的多继承容易出现：类的多个父类之间，如果有相同的成员\n         *      变量的时候，引用起来相当麻烦，运行时候产生各种各样的问题。\n         *\n         *      接口的特性：\n         *      1. 接口可以多重实现\n         *      2. 接口中声明的属性默认为 public static final 的，也只能是 public static final的\n         *      3. 接口中只能定义抽象方法，这些接口默认为 public 的，也只能是 public 的\n         *      4. 接口可以继承其他接口，并添加新的属性和成员方法\n         *\n         *      接口中定义的方法：函数指针\n         *\n         *\n         *      总结：\n         *          1. 内存分析贯穿始终\n         *          2. 对象和类的概念\n         *          3. 类（对象）之间的关系\n         *          4. 面向对象设计思想\n         *          5. class\n         *          6. new\n         *              引用的概念\n         *              构造方法的概念\n         *          7. 方法重载\n         *              构造方法重载\n         *          8. this\n         *          9. super\n         *          10. static\n         *          11. package & import\n         *          12. private default protected public\n         *          13. extends\n         *          14. override\n         *          15. final\n         *          16. Object\n         *               toString\n         *               equals\n         *          17. upcasting downcasting\n         *          18. Polymorphism/dynamic binding/late\n         *          19. abstract class\n         *          20. interface\n         *               implements\n         */\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0201OO.java",
    "content": "package com.basic.chapter0200;\n\n/**\n *\n * @author MarkShen1992\n * @since 20191105\n */\npublic class Chapter0201OO {\n    public static void main(String[] args) {\n        /**\n         * 成员变量\n         *     可以是Java语言中的任何一种数据类型，基本类型和引用类型\n         *     在定义成员变量时可以直接对其初始化，如果不对其初始化，\n         *     Java将使用默认的值进行初始化\n         *     byte 0\n         *     short 0\n         *     int 0\n         *     long 0L\n         *     char '\\u0000'\n         *     float 0.0F\n         *     double 0.0D\n         *     boolean false\n         *     引用类型 null\n         *\n         *      *成员变量在什么时候对其进行初始化，怎么初始化的?\n         *\n         * 局部变量：\n         *     声明 > 赋值 > 使用\n         */\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0202ValueTransferAndReferenceTransfer.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * 小程序分析内存，清楚理解值传递，引用传递\n *\n * 方法执行完毕，为方法分配的局部变量（stack内存）所分配的内存自动消失\n * Heap内存中的内存需要垃圾回收机制来做回收\n *\n * @author MarkShen1992\n * @since 20191106\n */\npublic class Chapter0202ValueTransferAndReferenceTransfer {\n    public static void main(String[] args) {\n        Chapter0202ValueTransferAndReferenceTransfer c = new Chapter0202ValueTransferAndReferenceTransfer();\n        int date = 9;\n        BirthDate bd = new BirthDate(1970, 7, 7 );\n        BirthDate bd2 = new BirthDate(2000, 1, 1);\n        c.change1(date);\n        System.out.println(date);\n        c.change2(bd);\n        System.out.println(bd);\n        c.change3(bd2);\n        System.out.println(bd2);\n    }\n\n    public void change1(int i) {\n        i = 1234;\n    }\n\n    public void change2(BirthDate b) {\n        b = new BirthDate(22, 2, 2004);\n    }\n\n    public void change3(BirthDate b) {\n        b.setDay(22);\n    }\n}\n\n/**\n * 出生日期\n */\nclass BirthDate {\n    private int year;\n    private int month;\n    private int day;\n\n    public BirthDate() {}\n\n    public BirthDate(int year, int month, int day) {\n        this.year = year;\n        this.month = month;\n        this.day = day;\n    }\n\n    public int getYear() {\n        return year;\n    }\n\n    public void setYear(int year) {\n        this.year = year;\n    }\n\n    public int getMonth() {\n        return month;\n    }\n\n    public void setMonth(int month) {\n        this.month = month;\n    }\n\n    public int getDay() {\n        return day;\n    }\n\n    public void setDay(int day) {\n        this.day = day;\n    }\n\n    @Override\n    public String toString() {\n        return \"BirthDate{\" +\n                \"year=\" + year +\n                \", month=\" + month +\n                \", day=\" + day +\n                '}';\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0203Point.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * 练习例子\n *\n * @author MarkShen1992\n * @since 20191107\n */\npublic class Chapter0203Point {\n    public static void main(String[] args) {\n        Point p = new Point(1, 2, 3);\n        Point p2 = new Point(0, 0, 0);\n        // 函数返回值，在内存中也有一块儿空间\n        double result = p.getDistance(p2);\n        System.out.println(result);\n    }\n}\n\nclass Point {\n    private double x, y, z;\n\n    public Point() {\n    }\n\n    public Point(double x, double y, double z) {\n        this.x = x;\n        this.y = y;\n        this.z = z;\n    }\n\n    public double getX() {\n        return x;\n    }\n\n    public void setX(double x) {\n        this.x = x;\n    }\n\n    public double getY() {\n        return y;\n    }\n\n    public void setY(double y) {\n        this.y = y;\n    }\n\n    public double getZ() {\n        return z;\n    }\n\n    public void setZ(double z) {\n        this.z = z;\n    }\n\n    public double getDistance(Point p) {\n        return Math.sqrt(\n            (this.x - p.getX()) * (this.x - p.getX()) +\n            (this.x - p.getX()) * (this.x - p.getX()) +\n            (this.z - p.getZ()) * (this.z - p.getZ())\n        );\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0204MethodOverload.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * 方法重载:指一个类中可以定义有相同的名字，单参数不同的多个方法，调用时会根据参数的不同\n * 调用不同的方法。\n * 重载方法参数特性：\n *  个数不同\n *  类型不同\n *  顺序不同\n *\n * 构造方法，普通方法皆可重载\n *\n * @author MarkShen1992\n * @since 20191107\n */\npublic class Chapter0204MethodOverload {\n\n    public static int add(int a, int b) {\n        return a + b;\n    }\n\n    // 不与第一个方法产生冲突\n//    public static void add(int a, int b) {\n//        System.out.println(a + b);\n//    }\n\n    public static int add(short a, short b) {\n        return a + b;\n    }\n\n    public static double add(double a, int b) {\n        return a + b;\n    }\n\n    public static double add(int a, double b) {\n        return a + b;\n    }\n\n    public static double add(double... args) {\n        double tmpVal = 0;\n        for (int i=0; i<args.length; i++) {\n            tmpVal += args[i];\n        }\n        return tmpVal;\n    }\n\n    public static void main(String[] args) {\n        System.out.println(add(1, 2));\n        System.out.println(add(1, 2.0));\n        System.out.println(add(1.0, 2));\n        System.out.println(add(1.0, 1.0));\n        System.out.println(add(1.0, 1.0, 1.0));\n        short a=1;\n        short b=2;\n        System.out.println(add(a, b));\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0205TestOverLoad.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * 练习例子\n *\n * @author MarkShen1992\n * @since 20191107\n */\npublic class Chapter0205TestOverLoad {\n    public static void main(String[] args) {\n        Person p = new Person();\n        Person p1 = new Person(400);\n        Person p2 = new Person(2, 500);\n        p.info();\n        p.info(\"ok\");\n    }\n}\n\nclass Person {\n\n    Person() {\n        id = 0;\n        age = 20;\n    }\n\n    Person(int _id) {\n        id = _id;\n        age = 23;\n    }\n\n    Person(int _id, int _age) {\n        id = _id;\n        age = _age;\n    }\n\n    // 成员变量定义\n    private int id;\n    private int age = 20;\n\n    // 方法定义\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int i) {\n        age = i;\n    }\n\n    public int getId() {\n        return id;\n    }\n\n    void info() {\n        System.out.println(\"my id is : \" + id);\n    }\n\n    void info(String t) {\n        System.out.println(t + \" id \" + id);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0206TestCircle.java",
    "content": "package com.basic.chapter0200;\n\nclass Point2 {\n    private double x;\n    private double y;\n\n    Point2(double x1, double y1) {\n        x = x1;\n        y = y1;\n    }\n\n    public double getX() {\n        return x;\n    }\n\n    public double getY() {\n        return y;\n    }\n\n    public void setX(double i) {\n        x = i;\n    }\n\n    public void setY(double i) {\n        y = i;\n    }\n}\n\nclass Circle {\n    private Point2 o;\n    private double radius;\n\n    Circle(Point2 p, double r) {\n        o = p;\n        radius = r;\n    }\n\n    Circle(double r) {\n        o = new Point2(0.0, 0.0);\n        radius = r;\n    }\n\n    boolean contains(Point2 p) {\n        double x = p.getX() - o.getX();\n        double y = p.getY() - o.getY();\n        if (x * x + y * y > radius * radius) return false;\n        else return true;\n    }\n\n\n    public void setO(double x, double y) {\n        o.setX(x);\n        o.setY(y);\n    }\n\n    public Point2 getO() {\n        return o;\n    }\n\n    public double getRadius() {\n        return radius;\n    }\n\n    public void setRadius(double r) {\n        radius = r;\n    }\n\n    public double area() {\n        return 3.14 * radius * radius;\n    }\n}\n\npublic class Chapter0206TestCircle {\n    public static void main(String args[]) {\n        Circle c1 = new Circle(new Point2(1.0, 2.0), 2.0);\n        Circle c2 = new Circle(5.0);\n        System.out.println(\"c1:(\" + c1.getO().getX() + \",\"\n                + c1.getO().getY() + \"),\" + c1.getRadius());\n        System.out.println(\"c2:(\" + c2.getO().getX()\n                + \",\" + c2.getO().getY() + \"),\" + c2.getRadius());\n        System.out.println(\"c1 area = \" + c1.area());\n        System.out.println(\"c1 area = \" + c2.area());\n        c1.setO(5, 6);\n        c2.setRadius(9.0);\n        System.out.println(\"c1:(\" + c1.getO().getX() + \",\"\n                + c1.getO().getY() + \"),\" + c1.getRadius());\n        System.out.println(\"c2:(\" + c2.getO().getX() + \",\"\n                + c2.getO().getY() + \"),\" + c2.getRadius());\n        System.out.println(\"c1 area = \" + c1.area());\n        System.out.println(\"c1 area = \" + c2.area());\n\n        Point2 p1 = new Point2(5.2, 6.3);\n        System.out.println(c1.contains(p1));\n        System.out.println(c1.contains(new Point2(10.0, 9.0)));\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0207this.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * this 关键字\n * 在类的方法定义中使用的this关键字代表使用该方法的对象的引用\n * 当必须指定当前使用方法的对象是谁的时候用this\n * 使用this处理类中构造方法中，成员变量和参数重名的问题\n * 当前对象的引用\n *\n * @author MarkShen1992\n * @since 20191113\n */\npublic class Chapter0207this {\n\n    int i = 0;\n\n    /**\n     * 原则：当你确定不了一个参数到底是哪个变量的时候，找离他最近的声明\n     *\n     */\n    public Chapter0207this(int i) {\n        this.i = i;\n    }\n\n    /**\n     * 链式编程\n     * 返回值在栈空间分配\n     *\n     * @return\n     */\n    public Chapter0207this increment() {\n        i ++;\n        return this;\n    }\n\n    public void print() {\n        System.out.println(\"i = \" + i);\n    }\n\n    public static void main(String[] args) {\n        Chapter0207this c = new Chapter0207this(1);\n        c.increment().increment().print();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0208static.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * static 关键字\n * static 修饰的成员变量为静态成员变量，它为该类的共有变量，在第一次使用时被初始化，对该类的所有\n * 对象来说，static 成员变量只有一份。\n * 用 static 声明的方法为静态方法，在调用该方法时，不会将对象的引用传给它，所有在静态方法中不可以\n * 访问非静态成员。\n * 静态方法不再是针对某个对象调用，所以不能访问非静态成员\n * 可以通过类名或对象引用调用 static 方法\n *\n * @author MarkShen1992\n * @since 20191113\n */\npublic class Chapter0208static {\n\n    // 存在于内存中数据区，Data Segment，可用于计数\n    static int i;\n\n    /**\n     * 静态初始化块\n     */\n    static {\n\n    }\n\n    public static void print() {\n        System.out.println(\"hello \" + i);\n    }\n\n    public static void main(String[] args) {\n        Chapter0208static.i = 10;\n        print();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0209TestInherit.java",
    "content": "package com.basic.chapter0200;\n\nclass FatherClass {\n    public int value;\n\n    public void f() {\n        value = 100;\n        System.out.println(\"FatherClass.value=\" + value);\n    }\n}\n\nclass ChildClass extends FatherClass {\n    public int value;\n\n    public void f() {\n        super.f();\n        value = 200;\n        System.out.println(\"ChildClass.value=\" + value);\n        System.out.println(value);\n        System.out.println(super.value);\n    }\n}\n\n/**\n * super 关键字\n *\n * @author MarkShen1992\n * @since 20191117\n */\npublic class Chapter0209TestInherit {\n    public static void main(String[] args) {\n        ChildClass cc = new ChildClass();\n        cc.f();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0210TestEquals.java",
    "content": "package com.basic.chapter0200;\n\nimport java.util.Objects;\n\npublic class Chapter0210TestEquals {\n    public static void main(String[] args) {\n        Cat c1 = new Cat(1, 2, 3);\n        Cat c2 = new Cat(1, 2, 3);\n        System.out.println(c1 == c2);\n        System.out.println(c1.equals(c2));\n\n        String s1 = new String(\"hello\");\n        String s2 = new String(\"hello\");\n        System.out.println(s1 == s2);\n        System.out.println(s1.equals(s2));\n    }\n}\n\nclass Cat {\n    int color;\n    int height, weight;\n\n    public Cat(int color, int height, int weight) {\n        this.color = color;\n        this.height = height;\n        this.weight = weight;\n    }\n\n    public boolean equals(Object obj) {\n        if (obj == null)\n        \treturn false;\n        else {\n            if (obj instanceof Cat) {\n                Cat c = (Cat) obj;\n                if (c.color == this.color && c.height == this.height && c.weight == this.weight) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n\t@Override\n\tpublic int hashCode() {\n\t\treturn Objects.hash(color, height, weight);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0211TestFinal.java",
    "content": "package com.basic.chapter0200;\n\npublic class Chapter0211TestFinal {\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\t//t.i = 8;\n\t}\n}\n\nfinal class T {\n\tfinal int i = 8;\n\tpublic final void m() {\n\t\t//j = 9;\n\t}\n}\n\n/**\n * T 是被 final 修饰的类， 不可以被继承\n */\n//class TT extends T {\n//\n//}"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0212TestInterface.java",
    "content": "package com.basic.chapter0200;\n\n/**\n * 接口测试\n *\n * @author MarkShen1992\n * @since 20191120\n */\npublic class Chapter0212TestInterface implements A, B {\n    public static void main(String[] args) {\n        Chapter0212TestInterface t = new Chapter0212TestInterface();\n        t.print();\n\n        A a = new Chapter0212TestInterface();\n        t.print(a);\n    }\n\n    @Override\n    public void print() {\n        System.out.println(\"hello world!\");\n    }\n\n    @Override\n    public void print(A a) {\n        System.out.println(a);\n    }\n}\n\ninterface A {\n    void print();\n}\n\ninterface B {\n    void print(A a);\n}\n\ninterface C {\n    void test();\n}\n\ninterface D extends C, A, B {\n    void test();\n    void sleep();\n    void sing();\n}\n\nclass F implements D {\n\n    @Override\n    public void print() {\n\n    }\n\n    @Override\n    public void print(A a) {\n\n    }\n\n    @Override\n    public void test() {\n\n    }\n\n    @Override\n    public void sleep() {\n\n    }\n\n    @Override\n    public void sing() {\n\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/Chapter0213DoubleBraceInitializationModel.java",
    "content": "package com.basic.chapter0200;\n\nimport java.util.UUID;\n\npublic class Chapter0213DoubleBraceInitializationModel {\n    public static void main(String[] args) {\n        // double brace initialization\n        // https://www.baeldung.com/java-double-brace-initialization\n        // this way can be used in making List, Set, Map, etc.\n        User u = new User() {\n            {\n                setUserId(UUID.randomUUID().toString());\n                setUserName(\"shenjy\");\n                setRealName(\"沈军禹\");\n            }\n        };\n        System.out.println(u);\n    }\n}\n\n/**\n * 用户Model\n */\nclass User {\n\n    private String userId;\n\n    private String userName;\n\n    private String realName;\n\n    public String getUserId() {\n        return userId;\n    }\n\n    public void setUserId(String userId) {\n        this.userId = userId;\n    }\n\n    public String getUserName() {\n        return userName;\n    }\n\n    public void setUserName(String userName) {\n        this.userName = userName;\n    }\n\n    public String getRealName() {\n        return realName;\n    }\n\n    public void setRealName(String realName) {\n        this.realName = realName;\n    }\n\n    @Override\n    public String toString() {\n        return \"User{\" + \"userId='\" + userId + '\\'' + \", userName='\" + userName + '\\'' + \", realName='\" + realName\n            + '\\'' + '}';\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/MessageFormatTest.java",
    "content": "package com.basic.chapter0200;\n\nimport java.text.MessageFormat;\nimport java.util.Date;\n\npublic class MessageFormatTest {\n    public static void main(String[] args) {\n        int planet = 7;\n        String event = \"a disturbance in the Force\";\n        String result = MessageFormat.format(\"At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.\",\n            planet, new Date(), event);\n        System.out.println(result);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0200/TestSuperSub.java",
    "content": "package com.basic.chapter0200;\n\nclass SuperClass {\n    private int n;\n\n    SuperClass() {\n        System.out.println(\"SuperClass()\");\n    }\n\n    SuperClass(int n) {\n        System.out.println(\"SuperClass(\" + n + \")\");\n        this.n = n;\n    }\n}\n\nclass SubClass extends SuperClass {\n    private int n;\n\n    SubClass(int n) {\n        super();\n        System.out.println(\"SubClass(\" + n + \")\");\n        this.n = n;\n    }\n\n    SubClass() {\n        super(300);\n        System.out.println(\"SubClass()\");\n    }\n}\n\n/**\n * 继承中的构造方法\n *   规则：\n *   1. 子类在构造的时候，要首先调用父类的构造方法\n *   2. super 关键字\n *   3. 如果调用了 super，必须写在子类构造方法的第一行\n *\n * @author MarkShen1992\n * @since 继承中的构造方法\n */\npublic class TestSuperSub {\n    public static void main(String arg[]) {\n        SubClass sc1 = new SubClass();\n        SubClass sc2 = new SubClass(400);\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0300/Chapter0300ExceptionIntroduction.java",
    "content": "package com.basic.chapter0300;\n\n/**\n * Exception\n *      异常的概念\n *      Java异常的分类\n *      异常的捕获和处理\n *      运行期出现的问题\n *\n *      观察错误的名字和行号特别重要\n *      程序是调出来的\n *\n * @author MarkShen1992\n * @since 20191121\n */\npublic class Chapter0300ExceptionIntroduction {\n    public static void main(String[] args) {\n        /**\n         * 对于数组越界问题，C, C++ 语言中会有问题，缓冲区溢出漏洞。\n         * 所以写C, C++ 程序的时候，一定要安全内容\n         *\n         * Java异常是Java提供的处理程序错误的一种机制\n         * 所谓错误是指在程序运行的时候发生的一些异常事件\n         * 设计好的程序应该在发生异常时提供异常处理的方法，使得程序不会因为异常的发生而阻断\n         * 或产生不可预期的后果。\n         * Java程序的执行过程中如果出现异常事件，可以生成一个异常对象，该异常对象封装了异常\n         * 事件的信息，并被提交给Java运行时系统，这个过程称为抛出异常。\n         * 当Java运行时系统接收到异常对象时，会寻找可以处理异常的方法，并把当前异常对象交给\n         * 其处理，这个过程称为捕获异常。\n         *\n         * try() {\n         *     ...代码\n         * } catch (XXXException e) {\n         *     捕获异常后处理\n         * } catch (YYYException e2) {\n         *     ...\n         * } finally {\n         *      产不产生异常，finally中的语句一定会执行\n         *     关闭资源\n         * }\n         *\n         * catch 异常的时候，要先 catch 具体的（小的）异常，然后再 catch 抽象的（大的）异常\n         */\n        try {\n            System.out.println(2 / 0);\n        } catch (ArithmeticException e) {\n            System.out.println(\"系统正在维护中，请稍后，请与管理员联系，谢谢\");\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0300/Chapter0301TestEx.java",
    "content": "package com.basic.chapter0300;\n\nimport java.io.*;\n\n/**\n * 异常处理\n *\n * @author MarkShen\n * @since 20191121\n */\npublic class Chapter0301TestEx {\n    public static void main(String[] args) {\n        try {\n            new Chapter0301TestEx().f2();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\t\t\n\t\t/*\n\t\tint[] arr = {1, 2, 3};\n\t\tSystem.out.println(arr[2]);\n\t\ttry {\n\t\t\tSystem.out.println(2/0);\n\t\t} catch (ArithmeticException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t*/\n\n        //TestEx te = new TestEx();\n        //te.m(0);\n\t\t\n\t\t/*\n\t\ttry {\n\t\t\tnew TestEx().m(0);\n\t\t} catch (ArithmeticException ae) {\n\t\t\tae.printStackTrace();\n\t\t}\n\t\t*/\n\n        FileInputStream in = null;\n        try {\n            in = new FileInputStream(\"myfile.txt\");\n            int b;\n            b = in.read();\n            while (b != -1) {\n                System.out.print((char) b);\n                b = in.read();\n            }\n        } catch (FileNotFoundException e) {\n            System.out.println(e.getMessage());\n        } catch (IOException e) {\n            e.printStackTrace();\n        } finally {\n            try {\n                in.close();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n\n    void m(int i) throws ArithmeticException {\n        if (i == 0)\n            throw new ArithmeticException(\"参数为0异常...\");\n    }\n\n    void f() throws FileNotFoundException, IOException {\n        FileInputStream in = new FileInputStream(\"myfile.txt\");\n        int b;\n        b = in.read();\n        while (b != -1) {\n            System.out.print((char) b);\n            b = in.read();\n        }\n    }\n\n    void f2() throws IOException {\n\t\t/*\n\t\ttry {\n\t\t\tf();\n\t\t} catch (FileNotFoundException e) {\n\t\t\tSystem.out.println(e.getMessage());\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t*/\n        f();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0300/Chapter0302MethodException.java",
    "content": "package com.basic.chapter0300;\n\n/**\n * 方法异常\n *\n * @author MarkShen\n * @since 20191121\n */\npublic class Chapter0302MethodException {\n    public static void main(String[] args) {\n        crunch(null);\n    }\n\n    static void crunch(int[] a) {\n        mash(a);\n    }\n    static void mash(int[] b) {\n        System.out.println(b[0]);\n    }\n}\n\n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0300/Chapter0303Junk.java",
    "content": "package com.basic.chapter0300;\n\n/**\n * Method Exception handle\n * 能处理的一定要处理，处理不了的往外抛\n * 多读设计精巧的源码，体会设计思想尤为重要\n *\n * 异常和继承之间的关系\n * 重写方法需要抛出与原方法所抛出异常类型一致异常或不抛出异常。\n *\n * @author MarkShen\n * @since 20191121\n */\npublic class Chapter0303Junk {\n    public static void main(String args[]) {\n        try {\n            a();\n        } catch (HighLevelException e) {\n            e.printStackTrace();\n        }\n    }\n\n    static void a() throws HighLevelException {\n        try {\n            b();\n        } catch (MidLevelException e) {\n            throw new HighLevelException(e);\n        }\n    }\n\n    static void b() throws MidLevelException {\n        c();\n    }\n\n    static void c() throws MidLevelException {\n        try {\n            d();\n        } catch (LowLevelException e) {\n            throw new MidLevelException(e);\n        }\n    }\n\n    static void d() throws LowLevelException {\n        e();\n    }\n\n    static void e() throws LowLevelException {\n        throw new LowLevelException();\n    }\n}\n\n/**\n * 使用自定义异常一般有如下步骤：\n * 1. 通过继承 java.lang.Exception类声明自己的异常类\n * 2. 在方法适当的位置生成自定义异常的实例，并用throw抛出\n * 3. 方法级使用 throws 语句声明该方法可能抛出的异常\n */\nclass HighLevelException extends Exception {\n    HighLevelException(Throwable cause) {\n        super(cause);\n    }\n}\n\nclass MidLevelException extends Exception {\n    MidLevelException(Throwable cause) {\n        super(cause);\n    }\n}\n\nclass LowLevelException extends Exception {\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Chapter0401ArrayIntroduction.java",
    "content": "package com.basic.chapter0400;\n\n/**\n * 数组[空间]介绍\n * 一维数组声明方式\n * type var[] 或者 type[] var\n * Java语言声明数组时不能指定其长度。\n * int[5] a; // 非法，但是c或c++语言是可以的，分配在占内存空间上\n * 元素为引用类型的数据中的每个元素都需要实例化\n *\n * 用数组模拟算法\n * 算法的演进\n * 数组的内存的布局\n *\n * @author MarkShen\n * @since 20191122\n */\npublic class Chapter0401ArrayIntroduction {\n    public static void main(String[] args) {\n        // 第一种：静态初始化\n        int[] a = {1, 3, 5, 7, 9};\n        for (int temp : a) {\n            System.out.println(temp);\n        }\n\n        // 第二种：动态初始化\n        int[] arr;\n        arr = new int[5];\n\n        // 给数组元素赋值\n        for (int i = 0; i < 5; i++) {\n            arr[i] = i;\n        }\n\n        // 变量数组元素\n        for (int j : arr) {\n            System.out.println(j);\n        }\n\n        // 二位数组静态初始化\n        int[][] arrA = {{1, 3}, {1, 2, 4, 5}, {2, 4, 6}};\n        // int[3][2] arrB = {{1, 2}, {2, 3}, {4, 5}};\n\n        // 二维数组赋值\n        int[][] test = new int[3][];\n        int[][] array = new int[3][3];\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                array[i][j] = 0;\n            }\n        }\n\n        // 二位数组遍历\n        System.out.println(\"二位数组的长度=\" + array.length);\n        for (int i = 0; i < array.length; i++) {\n            for (int j = 0; j < array[i].length; j++) {\n                System.out.println(array[i][j]);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Chapter0402TestArgs.java",
    "content": "package com.basic.chapter0400;\n\npublic class Chapter0402TestArgs {\n    public static void main(String[] args) {\n\t\t/*\n\t\tfor(int i=0; i<args.length; i++) {\n\t\t\tSystem.out.println(args[i]);\n\t\t}\n\t\t\n\t\tSystem.out.println(\"Usage: java Test \\\"n1\\\" \\\"op\\\" \\\"n2\\\"\");\n        */\n        if (args.length < 3) {\n            System.out.println(\n                    \"Usage: java Test \\\"n1\\\" \\\"op\\\" \\\"n2\\\"\");\n            System.exit(-1); // 系统非正常退出\n        }\n        // 基础类型的包装类\n        double d1 = Double.parseDouble(args[0]);\n        double d2 = Double.parseDouble(args[2]);\n        double d = 0;\n        if (args[1].equals(\"+\")) d = d1 + d2;\n        else if (args[1].equals(\"-\")) d = d1 - d2;\n        else if (args[1].equals(\"x\")) d = d1 * d2;\n        else if (args[1].equals(\"/\")) d = d1 / d2;\n        else {\n            System.out.println(\"Error operator!\");\n            System.exit(-1);\n        }\n        System.out.println(d);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Chapter0403SortAlgorithm.java",
    "content": "package com.basic.chapter0400;\n\n/**\n * 排序数组: 选择排序(Selection Sort)\n * 写程序先跑主流程，主流程跑通后再考虑程序的细节\n *\n * 如何分析一个你不熟悉的算法呢？\n * 在纸上 画图分析，分析i等于0, 1, 2, ...的情况, 找规律\n *\n * 十大经典排序算法（动图演示）\n * https://www.cnblogs.com/onepixel/articles/7674659.html\n *\n * @author MarkShen\n * @since 20191123\n */\npublic class Chapter0403SortAlgorithm {\n\n    // selection algorithm\n    private static int[] arr = {6, 9, 5, 4, 9, 12};\n    private static double[] arr2 = {0.1, 0.2, 0.3, 0.1};\n\n    // bubble sort algorithm\n    private static int[] arr3 = {1, 2, 4, 3, 9, 2};\n\n    public static void main(String[] args) {\n        int[] array = selectionSort(arr);\n        for (int i : array) {\n            System.out.println(i);\n        }\n\n        double[] arr = selectionSort(arr2);\n        for (double d : arr) {\n            System.out.println(d);\n        }\n    }\n\n    /**\n     * algorithm implementation method\n     * algorithm thinking:\n     *\n     * @param arr\n     * @return\n     */\n    private static int[] selectionSort(int[] arr) {\n        if (arr == null) {\n            return new int[0];\n        }\n        for (int i = 0; i < arr.length; i++) {\n            for (int j = i + 1; j < arr.length; j++) {\n                if (arr[i] > arr[j]) {\n                    int tmp = 0;\n                    tmp = arr[i];\n                    arr[i] = arr[j];\n                    arr[j] = tmp;\n                }\n            }\n        }\n        return arr;\n    }\n\n    /**\n     * 选择排序算法\n     *\n     * @param arr\n     * @return\n     */\n    private static double[] selectionSort(double[] arr) {\n        if (arr == null) {\n            return new double[0];\n        }\n        double len = arr.length;\n        int minIndex;\n        double temp;\n        for (int i = 0; i < len - 1; i++) {\n            minIndex = i;\n            for (int j = i + 1; j < len; j++) {\n                if (arr[j] < arr[minIndex]) {     // 寻找最小的数\n                    minIndex = j;                 // 将最小数的索引保存\n                }\n            }\n            if (minIndex != i) {\n                temp = arr[i];\n                arr[i] = arr[minIndex];\n                arr[minIndex] = temp;\n            }\n        }\n        return arr;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Chapter0404TestDateSort.java",
    "content": "package com.basic.chapter0400;\n\n/**\n * 对对象进行排序\n *\n * @author MarkShen\n * @since 20191124\n */\npublic class Chapter0404TestDateSort {\n    public static void main(String[] args) {\n        Date[] days = new Date[5];\n        days[0] = new Date(2006, 5, 4);\n        days[1] = new Date(2006, 7, 4);\n        days[2] = new Date(2008, 5, 4);\n        days[3] = new Date(2004, 5, 9);\n        days[4] = new Date(2004, 5, 4);\n\n        Date d = new Date(2006, 7, 4);\n        String str = String.valueOf(d);\n        // str = d.toString();\n        bubbleSort(days);\n\n        for (int i = 0; i < days.length; i++) {\n            System.out.println(days[i]);\n        }\n\n        System.out.println(binarySearch(days, d));\n    }\n\n    public static Date[] bubbleSort(Date[] a) {\n        int len = a.length;\n        for (int i = len - 1; i >= 1; i--) {\n            for (int j = 0; j <= i - 1; j++) {\n                if (a[j].compare(a[j + 1]) > 0) {\n                    Date temp = a[j];\n                    a[j] = a[j + 1];\n                    a[j + 1] = temp;\n                }\n            }\n        }\n        return a;\n    }\n\n    public static int binarySearch(Date[] days, Date d) {\n        if (days.length == 0) return -1;\n\n        int startPos = 0;\n        int endPos = days.length - 1;\n        int m = (startPos + endPos) / 2;\n        while (startPos <= endPos) {\n            if (d.compare(days[m]) == 0) return m;\n            if (d.compare(days[m]) > 0) {\n                startPos = m + 1;\n            }\n            if (d.compare(days[m]) < 0) {\n                endPos = m - 1;\n            }\n            m = (startPos + endPos) / 2;\n        }\n        return -1;\n    }\n}\n\nclass Date {\n    int year, month, day;\n\n    Date(int y, int m, int d) {\n        year = y;\n        month = m;\n        day = d;\n    }\n\n    public int compare(Date date) {\n        return year > date.year ? 1\n                : year < date.year ? -1\n                : month > date.month ? 1\n                : month < date.month ? -1\n                : day > date.day ? 1\n                : day < date.day ? -1 : 0;\n    }\n\n    public String toString() {\n        return \"Year:Month:Day -- \" + year + \"-\" + month + \"-\" + day;\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Chapter0405TestSearch.java",
    "content": "package com.basic.chapter0400;\n\n/**\n * 搜索算法建立在排序算法的基础之上\n * 二分法查找算法\n *\n * @author MarkShen\n * @since 20191124\n */\npublic class Chapter0405TestSearch {\n    public static void main(String[] args) {\n        int a[] = {1, 3, 6, 8, 9, 10, 12, 18, 20, 34};\n        int i = 12;\n        //System.out.println(search(a, i));\n        System.out.println(binarySearch(a, i));\n    }\n\n    public static int search(int[] a, int num) {\n        for (int i = 0; i < a.length; i++) {\n            if (a[i] == num) return i;\n        }\n        return -1;\n    }\n\n    public static int binarySearch(int[] a, int num) {\n        if (a.length == 0) return -1;\n\n        int startPos = 0;\n        int endPos = a.length - 1;\n        int m = (startPos + endPos) / 2;\n        while (startPos <= endPos) {\n            if (num == a[m]) return m;\n            if (num > a[m]) {\n                startPos = m + 1;\n            }\n            if (num < a[m]) {\n                endPos = m - 1;\n            }\n            m = (startPos + endPos) / 2;\n        }\n        return -1;\n    }\n\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Chapter0406TestArrayCopy.java",
    "content": "package com.basic.chapter0400;\n\npublic class Chapter0406TestArrayCopy {\n    public static void main(String args[]) {\n        String[] s = {\"Mircosoft\", \"IBM\", \"Sun\", \"Oracle\", \"Apple\"};\n        String[] sBak = new String[6];\n        System.arraycopy(s, 0, sBak, 0, s.length);\n\n        for (int i = 0; i < sBak.length; i++) {\n            System.out.print(sBak[i] + \" \");\n        }\n\n        System.out.println();\n        int[][] intArray = {{1, 2}, {1, 2, 3}, {3, 4}};\n        int[][] intArrayBak = new int[3][];\n\n        System.arraycopy(intArray, 0, intArrayBak, 0, intArray.length);\n        intArrayBak[2][1] = 100;\n\n        for (int i = 0; i < intArray.length; i++) {\n            for (int j = 0; j < intArray[i].length; j++) {\n                System.out.print(intArray[i][j] + \"  \");\n            }\n            System.out.println();\n        }\n\n        // Arrays 类中的数组的copyof方法\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Count3Quit.java",
    "content": "package com.basic.chapter0400;\n\n/**\n * 数三退一\n *\n * @author MarkShen\n * @since 20191124\n */\npublic class Count3Quit {\n    public static void main(String[] args) {\n        boolean[] arr = new boolean[500];\n        for (int i = 0; i < arr.length; i++) {\n            arr[i] = true;\n        }\n\n        int leftCount = arr.length;\n        int countNum = 0;\n        int index = 0;\n\n        while (leftCount > 1) {\n            if (arr[index] == true) {\n                countNum++;\n                if (countNum == 3) {\n                    countNum = 0;\n                    arr[index] = false;\n                    leftCount--;\n                }\n            }\n\n            index++;\n\n            if (index == arr.length) {\n                index = 0;\n            }\n        }\n\n        for (int i = 0; i < arr.length; i++) {\n            if (arr[i] == true) {\n                System.out.println(i);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0400/Count3Quit2.java",
    "content": "package com.basic.chapter0400;\n\n/**\n * 数三退一\n *\n * @author MarkShen\n * @since 20191124\n */\npublic class Count3Quit2 {\n    public static void main(String[] args) {\n        KidCircle kc = new KidCircle(500);\n        int countNum = 0;\n        Kid k = kc.first;\n        while (kc.count > 1) {\n            countNum++;\n            if (countNum == 3) {\n                countNum = 0;\n                kc.delete(k);\n            }\n            k = k.right;\n        }\n\n        System.out.println(kc.first.id);\n    }\n}\n\nclass Kid {\n    int id;\n    Kid left;\n    Kid right;\n}\n\nclass KidCircle {\n    int count = 0;\n    Kid first, last;\n\n    KidCircle(int n) {\n        for (int i = 0; i < n; i++) {\n            add();\n        }\n    }\n\n    void add() {\n        Kid k = new Kid();\n        k.id = count;\n        if (count <= 0) {\n            first = k;\n            last = k;\n            k.left = k;\n            k.right = k;\n        } else {\n            last.right = k;\n            k.left = last;\n            k.right = first;\n            first.left = k;\n            last = k;\n        }\n        count++;\n    }\n\n    void delete(Kid k) {\n        if (count <= 0) {\n            return;\n        } else if (count == 1) {\n            first = last = null;\n        } else {\n            k.left.right = k.right;\n            k.right.left = k.left;\n\n            if (k == first) {\n                first = k.right;\n            } else if (k == last) {\n                last = k.left;\n            }\n        }\n        count--;\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0501CommonUseClass.java",
    "content": "package com.basic.chapter0500;\n\n/**\n * 常用类介绍\n * 字符串\n * 基本类型包装类\n * Math类\n * File类\n * 枚举类\n */\npublic class Chapter0501CommonUseClass {\n    public static void main(String[] args) {\n        /**\n         *\n         */\n        String s1 = \"hello\";\n        String s2 = \"world\";\n        String s3 = \"hello\";\n        System.out.println(s1 == s3);\n\n        String s4 = \"he\" + \"llo\";\n        System.out.println(s3 == s4);\n\n        String s5 = new String(\"hello\");\n        System.out.println(s3 == s5);\n        System.out.println(s3.equals(s5));\n\n        String s6 = new String(\"he\");\n        String s7 = s6 + \"llo\";\n        System.out.println(s3 == s7);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0502TestString2.java",
    "content": "package com.basic.chapter0500;\n\n/**\n * String\n *\n * @author MarkShen\n * @since 20191127\n */\npublic class Chapter0502TestString2 {\n    public static void main(String[] args) {\n        String s1 = \"Sun java\", s2 = \"sun Java\";\n        System.out.println(s1.charAt(1));\n        System.out.println(s2.length());\n        System.out.println(s1.indexOf(\"java\"));\n        System.out.println(s1.indexOf(\"Java\"));\n        System.out.println(s1.equals(s2));\n        System.out.println(s1.equalsIgnoreCase(s2));\n\n        String s3 = \"我是程序员，我在学Java!\";\n        System.out.println(s3.replace(\"我\", \"你\"));\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0503TestString3.java",
    "content": "package com.basic.chapter0500;\n\nimport java.util.Date;\n\n/**\n * String\n *\n * @author MarkShen\n * @since 20191127\n */\npublic class Chapter0503TestString3 {\n    public static void main(String[] args) {\n        String s1 = \"Welcome to Java world!\";\n        System.out.println(s1.codePointAt(0));\n        System.out.println(s1.codePointBefore(1));\n        System.out.println(s1.codePointCount(0, 2));\n        System.out.println(s1.compareTo(\"Java world!\"));\n        System.out.println(s1.concat(\"+\"));\n        System.out.println(s1.contains(\"Java\"));\n        System.out.println(s1.contentEquals(\"Welcome to Java world!\"));\n        System.out.println(s1.toUpperCase());\n        System.out.println(s1.toLowerCase());\n        System.out.println(String.valueOf(3.14));\n        System.out.println(s1.trim());\n        System.out.println(s1.toCharArray().length);\n        System.out.println(s1.substring(1));\n        System.out.println(s1.substring(0, 1));\n        System.out.println(s1.subSequence(0, 1));\n        System.out.println(s1.startsWith(\"Welcome\"));\n        System.out.println(s1.startsWith(\"Welcome\", 5));\n        System.out.println(s1.split(\" \").length);\n        System.out.println(\"java.lang\".split(\"\\\\.\").length);\n\n        Date d = new Date();\n        System.out.println(d);\n\n        // 计算j是几位数\n        int j = 1234657;\n        String num = String.valueOf(j);\n        System.out.println(\"j是\" + num.length() + \"位数.\");\n\n        String s2 = \"shen,jun,yu\";\n        System.out.println(s2.split(\",\").length);\n\n        String s3 = \"asjljladjflAJSDLAJDSAJS,,,...,ASJDS\";\n        System.out.println(\"大写字符数: \" + countA2Z(s3));\n        System.out.println(\"小写字符数：\" + counta2z(s3));\n        System.out.println(\"其它字符数：\" + countOtherCharacter(s3));\n        System.out.println(s3.length());\n    }\n\n    /**\n     * 计算大写字符数量\n     *\n     * @param string\n     * @return\n     */\n    private static int countA2Z(String string) {\n        char[] chars = string.toCharArray();\n        int count = 0;\n        for (char c : chars) {\n            if ('A' <= c && c <= 'Z') {\n                count ++;\n            }\n        }\n        return count;\n    }\n\n    private static int countLowerCase(String string) {\n        int count = 0;\n        for (int i=0; i<string.length(); i++) {\n            char tmp = string.charAt(i); // 注意 charAt 方法的使用\n            if ('A' <= tmp && tmp <= 'Z') {\n                count ++;\n            }\n        }\n        return count;\n    }\n\n    private static int countLowerCase2(String string) {\n        String s1 = \"abcdefghijklmnopqrstuvwxyz\";\n        int count = 0;\n        for (int i=0; i<string.length(); i++) {\n            char tmp = string.charAt(i); // 注意 charAt 方法的使用\n            if (s1.indexOf(tmp) != -1) {\n                count ++;\n            }\n        }\n        return count;\n    }\n\n    /**\n     * 计算小写字符数量\n     *\n     * @param string\n     * @return\n     */\n    private static int counta2z(String string) {\n        char[] chars = string.toCharArray();\n        int count = 0;\n        for (char c : chars) {\n            if ('a' <= c && c <= 'z') {\n                count ++;\n            }\n        }\n        return count;\n    }\n\n    /**\n     * 计算其他字符数个数\n     *\n     * @param string\n     * @return\n     */\n    private static int countOtherCharacter(String string) {\n        return string.length() - countA2Z(string) - counta2z(string);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0504TestString.java",
    "content": "package com.basic.chapter0500;\n\nimport java.util.regex.*;\npublic class Chapter0504TestString {\n\tpublic static void main(String[] args) {\n\t\t\n\t\t//String s = \"AaaaABBBBcc&^%adfsfdCCOOkk99876 _haHA\";\n\t\t//int lCount = 0, uCount = 0, oCount = 0;\n\t\t/*\n\t\tfor(int i=0; i<s.length(); i++) {\n\t\t\tchar c = s.charAt(i);\n\t\t\tif(c >= 'a' && c <= 'z') {\n\t\t\t\tlCount ++;\n\t\t\t} else if (c >='A' && c <= 'Z') {\n\t\t\t\tuCount ++;\n\t\t\t} else {\n\t\t\t\toCount ++;\n\t\t\t}\n\t\t}\n\t\t*/\n\t\t/*\n\t\tString sL = \"abcdefghijklmnopqrstuvwxyz\";\n\t\tString sU = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\t\tfor(int i=0; i<s.length(); i++) {\n\t\t\tchar c = s.charAt(i);\n\t\t\tif(sL.indexOf(c) != -1) {\n\t\t\t\tlCount ++;\n\t\t\t} else if (sU.indexOf(c) != -1) {\n\t\t\t\tuCount ++;\n\t\t\t} else {\n\t\t\t\toCount ++;\n\t\t\t}\n\t\t}\n\t\t*/\n\t\t\n\t\t/*\n\t\tfor(int i=0; i<s.length(); i++) {\n\t\t\tchar c = s.charAt(i);\n\t\t\tif(Character.isLowerCase(c)) {\n\t\t\t\tlCount ++;\n\t\t\t} else if (Character.isUpperCase(c)) {\n\t\t\t\tuCount ++;\n\t\t\t} else {\n\t\t\t\toCount ++;\n\t\t\t}\n\t\t}\n\t\t\n\t\tSystem.out.println(lCount + \" \" + uCount + \" \" + oCount);\n\t\t*/\n\t\tString s = \"sunjavahpjavaokjavajjavahahajavajavagoodjava\";\n\t\t\n\t\tString sToFind = \"java\";\n\t\tint count = 0;\n\t\tint index = -1;\n\t\t\n\t\twhile((index = s.indexOf(sToFind)) != -1) {\n\t\t\ts = s.substring(index + sToFind.length());\n\t\t\tcount ++;\n\t\t}\n\t\t\n\t\tSystem.out.println(count);\n\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0505StringBuffer.java",
    "content": "package com.basic.chapter0500;\n\n/**\n * StringBuffer\n *\n * @author MarkShen\n * @since 20191129\n */\npublic class Chapter0505StringBuffer {\n    public static void main(String[] args) {\n        String s = \"Microsoft\";\n        char[] a = {'a', 'b', 'c'};\n        StringBuilder sb = new StringBuilder(s);\n        sb.append(\"/\").append(\"IBM\")\n                .append(\"/\").append(\"Sun\");\n        sb.insert(0, a);\n        System.out.println(sb);\n        System.out.println(sb.reverse());\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0506BasicTypeWrap.java",
    "content": "package com.basic.chapter0500;\n\n/**\n * StringBuffer\n *\n * @author MarkShen\n * @since 20191129\n */\npublic class Chapter0506BasicTypeWrap {\n    public static void main(String[] args) {\n        boolean b = false;\n        Boolean b2 = Boolean.TRUE;\n\n        int a = 10;\n        Integer a2 = 10;\n\n        byte by = 1;\n        Byte by2 = 2;\n\n        short sh = 1;\n        Short sh2 = 2;\n\n        long l = 12L;\n        Long l2 = 23L;\n\n        char c = 'c';\n        Character c2 = 'c';\n\n        float f1 = 3.14f;\n        Float f2 = 3.14f;\n\n        double d = 3.14;\n        Double d2 = 3.14;\n\n        // 具体值参考Java API\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0507ArrayParser.java",
    "content": "package com.basic.chapter0500;\n\n/**\n * 解题程序\n *\n * @author MarkShen\n * @since 20191129\n */\npublic class Chapter0507ArrayParser {\n    public static void main(String[] args) {\n        double[][] d;\n        String s = \"1,2;3,4,5;6,7,8\";\n        String[] sFirst = s.split(\";\");\n        d = new double[sFirst.length][];\n        for (int i = 0; i < sFirst.length; i++) {\n            String[] sSecond = sFirst[i].split(\",\");\n            d[i] = new double[sSecond.length];\n            for (int j = 0; j < sSecond.length; j++) {\n\n                d[i][j] = Double.parseDouble(sSecond[j]);\n\n            }\n        }\n\n        for (int i = 0; i < d.length; i++) {\n            for (int j = 0; j < d[i].length; j++) {\n                System.out.print(d[i][j] + \" \");\n            }\n            System.out.println();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0508TestMath.java",
    "content": "package com.basic.chapter0500;\n\n/**\n * Math 测试类\n * 图形学，游戏中可以使用Math类中的方法\n *\n * @MarkShen\n * @since 20191129\n */\npublic class Chapter0508TestMath {\n    public static void main(String[] args) {\n        System.out.println(Math.E);\n        // Math 中的方法，请多查看Java API进行查询\n        System.out.println(Math.max(1, 3));\n        // 计算机中时间存储：从1970年1月1日0时0分0秒0毫秒 到 目前为止的毫秒数\n        // 效率比较高\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0509TestFile.java",
    "content": "package com.basic.chapter0500;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * File 测试\n *\n * @author MarkShen\n * @since 20191130\n */\npublic class Chapter0509TestFile {\n    public static void main(String[] args) {\n        // File仅仅是内存中的一个对象\n        String separator = File.separator;\n        String filename = \"myfile.txt\";\n        String directory = \"mydir1\" + separator + \"mydir2\";\n        //String directory = \"mydir1/mydir2\";\n\n        // 不推荐这种写法\n        //String directory = \"mydir1\\\\mydir2\";\n        File f = new File(directory, filename);\n        if (f.exists()) {\n            System.out.println(\"文件名：\" + f.getAbsolutePath());\n            System.out.println(\"文件大小：\" + f.length());\n        } else {\n            f.getParentFile().mkdirs();\n            try {\n                f.createNewFile();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0510FileList.java",
    "content": "package com.basic.chapter0500;\n\nimport java.io.*;\n\n/**\n * windows 下 tree命令\n */\npublic class Chapter0510FileList {\n    public static void main(String[] args) {\n        File f = new File(\"d:/A\");\n        System.out.println(f.getName());\n        tree(f, 1);\n    }\n\n    private static void tree(File f, int level) {\n        String preStr = \"\";\n        for (int i = 0; i < level; i++) {\n            preStr += \"    \";\n        }\n\n        File[] childs = f.listFiles();\n        for (int i = 0; i < childs.length; i++) {\n            System.out.println(preStr + childs[i].getName());\n            if (childs[i].isDirectory()) {\n                tree(childs[i], level + 1);\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0500/Chapter0511TestEnum.java",
    "content": "package com.basic.chapter0500;\n\n/**\n * 只能取特定值中的一个\n * 使用 enum 关键字\n * 是java.lang.Enum类型\n *\n * @author MarkShen\n * @since 20191209\n */\npublic class Chapter0511TestEnum {\n\tpublic enum MyColor { red, green, blue };\n\tpublic enum MyDoorOpener {me, mywife};\n\t\n\tpublic static void main(String[] args) {\n\t\tMyColor m = MyColor.red;\n\t\tswitch(m) {\n\t\t\tcase red:\n\t\t\t\tSystem.out.println(\"red\");\n\t\t\t\tbreak;\n\t\t\tcase green:\n\t\t\t\tSystem.out.println(\"green\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tSystem.out.println(\"default\");\n\t\t}\n\t\tSystem.out.println(m);\n\t}\n}\n\n/**\n * 总结：\n * String相关\n * \t正则表达式\n * 基础类型包装类\n * Math\n * File\n * \t递归\n * 枚举类型\n */"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/BasicContainer.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.*;\n\n/**\n * 三流的公司卖产品\n * 二流的公司卖服务\n * 一流的公司卖标准\n */\npublic class BasicContainer {\n    public static void main(String[] args) {\n        // 无序不可以重复\n        Collection c = new HashSet();\n        c.add(\"hello\");\n        c.add(new Name(\"f1\", \"l1\"));\n        c.add(new Integer(100));\n        c.remove(\"hello\");\n        c.remove(new Integer(100));\n        System.out.println(c.remove(new Name(\"f1\", \"l1\")));\n        System.out.println(c);\n    }\n}\n\nclass Name implements Comparable {\n    private String firstName, lastName;\n\n    public Name(String firstName, String lastName) {\n        this.firstName = firstName;\n        this.lastName = lastName;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public String toString() {\n        return firstName + \" \" + lastName;\n    }\n\n    /**\n     * 如果两个对象 equals, 那么这两个对象的hashcode相等\n     *\n     * @param obj\n     * @return\n     */\n    public boolean equals(Object obj) {\n        if (obj instanceof Name) {\n            Name name = (Name) obj;\n            return (firstName.equals(name.firstName))\n                    && (lastName.equals(name.lastName));\n        }\n        return super.equals(obj);\n    }\n\n    /**\n     * 使用场景：\n     * 当这个对象用在Map接口里里面作为 key 的时候需要用到 hashCode().\n     * 相等的对象应该具有享同的hash code, 非常适合做 索引。对象作为索引的时候\n     * <p>\n     * 原则：重写一个对象的 equals方法时，必须同时重写 hashCode方法\n     * 两个对象 equals，两个对象必须拥有相同的 hashcode.\n     * <p>\n     * 扩展：hashcode算法\n     *\n     * @return\n     */\n    public int hashCode() {\n        return firstName.hashCode();\n    }\n\n    public int compareTo(Object o) {\n        Name n = (Name) o;\n        int lastCmp = lastName.compareTo(n.lastName);\n        return lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName);\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/BasicGeneric.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.*;\n\n/**\n * Java 泛型底层:\n * https://www.cnblogs.com/liang1101/p/6407871.html\n *\n * @author MarkShen\n * @since 20191221\n */\npublic class BasicGeneric {\n    public static void main(String[] args) {\n        /**\n         * 泛型起因：\n         *  JDK1.4以前类型不明确\n         *      装入集合的类型被当作Object被对待，从而失去自己实际的类型\n         *      从集合中取出时往往需要转型，效率低，容易产生错误\n         * 解决方法：\n         *  在定义集合的时候，同时定义集合中元素的类型\n         *      可在定义Collection的时候指定\n         *      也可在循环时用Iterator指定\n         *\n         * 好处：\n         *  增强程序的可读性和稳定性\n         */\n        // 有序可以重复\n        List<String> c = new ArrayList<String>();\n        c.add(\"aaa\");\n        c.add(\"bbb\");\n        c.add(\"ccc\");\n        for (int i = 0; i < c.size(); i++) {\n            String s = c.get(i);\n            System.out.println(s);\n        }\n        c.add(1, \"insert\");\n        System.out.println();\n        for (String s : c) {\n            System.out.println(s);\n        }\n\n        Collection<String> c2 = new HashSet<String>();\n        c2.add(\"aaa\");\n        c2.add(\"bbb\");\n        c2.add(\"ccc\");\n        for (Iterator<String> it = c2.iterator(); it.hasNext(); ) {\n            String s = it.next();\n            System.out.println(s);\n        }\n    }\n}\n\nclass MyName implements Comparable<MyName> {\n    int age;\n\n    public int compareTo(MyName mn) {\n        if (this.age > mn.age) return 1;\n        else if (this.age < mn.age) return -1;\n        else return 0;\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/CollectionsTest.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.Collections;\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * 工具类测试 Collections\n *\n * @author MarkShen\n * @since 20191217\n */\npublic class CollectionsTest {\n    public static void main(String[] args) {\n        List<String> strs = new LinkedList<>();\n\n        for (int i = 0; i < 10; i++) {\n            strs.add(\"a\" + i);\n        }\n        System.out.println(strs);\n\n        Collections.shuffle(strs);\n        System.out.println(strs);\n\n        Collections.reverse(strs);\n        System.out.println(strs);\n\n        Collections.sort(strs);\n        System.out.println(strs);\n        System.out.println(Collections.binarySearch(strs, \"a5\"));\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/DataStructureSelection.java",
    "content": "package com.basic.chapter0600;\n\n/**\n * 数据结构选择\n */\npublic class DataStructureSelection {\n    public static void main(String[] args) {\n        // 读快写慢 ArrayList 基于数组实现\n        // 写快读慢 LinkedList 基于链表实现\n        // 介于两者中间 Hash\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/EnhancedFor.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.*;\n\npublic class EnhancedFor {\n    public static void main(String[] args) {\n        int[] arr = {1, 2, 3, 4, 5};\n        for (int i : arr) {\n            System.out.println(i);\n        }\n\n        Collection c = new ArrayList();\n        c.add(new String(\"aaa\"));\n        c.add(new String(\"bbb\"));\n        c.add(new String(\"ccc\"));\n        for (Object o : c) {\n            System.out.println(o);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/IteratorTest.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * Iterator 测试\n *\n * @author MarkShen\n * @since 20191210\n */\npublic class IteratorTest {\n    public static void main(String[] args) {\n        // List 有序，可以重复\n        List<String> list = new ArrayList<>();\n        list.add(\"a\");\n        list.add(\"b\");\n        list.add(\"c\");\n        list.add(\"d\");\n\n        for (Iterator it = list.iterator(); it.hasNext(); ) {\n            if (\"d\".equals(it.next())) {\n                it.remove();\n                // list.remove(\"d\");  // 会抛出 java.util.ConcurrentModificationException 异常\n            }\n        }\n\n        for (String str : list) {\n            System.out.println(str);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/SetTest.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Set：无序，不可重复\n *\n * @author MarkShen\n * @since 20191210\n */\npublic class SetTest {\n    public static void main(String[] args) {\n        Set<String> set = new HashSet<>();\n        set.add(\"a\");\n        set.add(\"a\");\n        set.add(\"b\");\n\n        for (String str : set) {\n            System.out.println(str);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/TestArgsWords.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.*;\n\n/**\n * 参数中每个单词出现的次数\n * auto-boxing\n * auto-unboxing\n *\n * @author MarkShen\n * @since 20191221\n */\npublic class TestArgsWords {\n    // private static final Integer ONE = new Integer(1);\n    private static final int ONE = 1;\n\n    public static void main(String args[]) {\n        Map m = new HashMap();\n        for (int i = 0; i < args.length; i++) {\n            //Integer freq = (Integer) m.get(args[i]);\n\n            int freq = (Integer) m.get(args[i]) == null ? 0 : (Integer) m.get(args[i]);\n            //m.put(args[i],(freq == null? ONE : new Integer(freq.intValue() + 1)));\n            m.put(args[i], freq == 0 ? ONE : freq + 1);\n        }\n        System.out.println(m.size() + \" distinct words detected:\");\n        System.out.println(m);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/TestArgsWords2.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.*;\n\npublic class TestArgsWords2 {\n    private static final int ONE = 1;\n\n    public static void main(String args[]) {\n        Map<String, Integer> m = new HashMap<String, Integer>();\n        for (int i = 0; i < args.length; i++) {\n\n            if (!m.containsKey(args[i])) {\n                m.put(args[i], ONE);\n            } else {\n                int freq = m.get(args[i]);\n                m.put(args[i], freq + 1);\n            }\n\n        }\n        System.out.println(m.size() + \" distinct words detected:\");\n        System.out.println(m);\n\n        System.out.println(\"通过Map.entrySet使用iterator遍历key和value：\");\n        Iterator<Map.Entry<String, Integer>> it = m.entrySet().iterator();\n        while (it.hasNext()) {\n            Map.Entry<String, Integer> entry = it.next();\n            System.out.println(\"key= \" + entry.getKey() + \" and value= \" + entry.getValue());\n        }\n\n        System.out.println(\"通过Map.entrySet遍历key和value\");\n        for (Map.Entry<String, Integer> entry : m.entrySet()) {\n            System.out.println(\"key= \" + entry.getKey() + \" and value= \" + entry.getValue());\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/TestMap.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.*;\n\n/**\n * key-value\n * Auto boxing unboxing\n * Java 自动打包，解包对性能的影响\n * https://www.cnblogs.com/kakaku/articles/1320191.html\n *\n * @author MarkShen\n * @since 20191211\n */\npublic class TestMap {\n    public static void main(String args[]) {\n        Map m1 = new HashMap();\n        Map m2 = new TreeMap();\n        //m1.put(\"one\",new Integer(1));\n        m1.put(\"one\", 1);\n        //m1.put(\"two\",new Integer(2));\n        m1.put(\"two\", 2);\n        //m1.put(\"three\",new Integer(3));\n        m1.put(\"three\", 3);\n        //m2.put(\"A\",new Integer(1));\n        m2.put(\"A\", 1);\n        //m2.put(\"B\",new Integer(2));\n        m2.put(\"B\", 2);\n        System.out.println(m1.size());\n        System.out.println(m1.containsKey(\"one\"));\n        System.out.println\n                //(m2.containsValue(new Integer(1)));\n                        (m2.containsValue(1));\n        if (m1.containsKey(\"two\")) {\n            //int i = ((Integer)m1.get(\"two\")).intValue();\n            int i = (Integer) m1.get(\"two\");\n            System.out.println(i);\n        }\n        Map m3 = new HashMap(m1);\n        m3.putAll(m2);\n        System.out.println(m3);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0600/TestMap2.java",
    "content": "package com.basic.chapter0600;\n\nimport java.util.*;\n\n/**\n * 两个类如果equals,那么他们之间的hashcode必须一样\n * <p>\n * 多读Map接口对应的API, JavaDoc\n */\npublic class TestMap2 {\n    public static void main(String args[]) {\n        Map<String, Integer> m1 = new HashMap<String, Integer>();\n        m1.put(\"one\", 1);\n        m1.put(\"two\", 2);\n        m1.put(\"three\", 3);\n\n        System.out.println(m1.size());\n        System.out.println(m1.containsKey(\"one\"));\n\n        if (m1.containsKey(\"two\")) {\n            // int i = ((Integer)m1.get(\"two\")).intValue();\n            int i = m1.get(\"two\");\n            System.out.println(i);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/FileCopy.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class FileCopy {\n    public static void main(String[] args) {\n        int b = 0;\n        FileReader in = null;\n        FileWriter out = null;\n        try {\n            in = new FileReader(\"d:/share/java/HelloWorld.java\");\n            out = new FileWriter(\"d:/share/java/io/HW.java\");\n            while ((b = in.read()) != -1) {\n                out.write(b);\n            }\n            out.close();\n            in.close();\n        } catch (FileNotFoundException e2) {\n            e2.printStackTrace();\n            System.exit(-1);\n        } catch (IOException e1) {\n            e1.printStackTrace();\n            System.exit(-1);\n        }\n        System.out.println(\"success\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/HelloWorld.java",
    "content": "package com.basic.chapter0700;\n\n/**\n * java.io.*;\n * io包裝的类\n * 流的分类：\n * 方向(站在程序的角度)：输入流，输出流\n * 处理数据单位：字节(1 byte)流，字符(2 bytes)流\n * 功能：节点流，处理流\n * <p>\n * 一定要多差Java API\n *\n * @author MarkShen\n * @since 20191221\n */\npublic class HelloWorld {\n\n    static int j = 9;\n\n    public static void main(String[] asdfasf) {\n        System.out.println(\"HW\");\n        System.out.println(123);\n        System.out.println(j);\n        int i = 8;\n    }\n\n    public static void m() {\n    }\n\n}\n\nclass TT {\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestBufferStream1.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestBufferStream1 {\n    public static void main(String[] args) {\n        try {\n            FileInputStream fis =\n                    new FileInputStream(\"d:\\\\share\\\\java\\\\HelloWorld.java\");\n            BufferedInputStream bis =\n                    new BufferedInputStream(fis);\n            int c = 0;\n            System.out.println(bis.read());\n            System.out.println(bis.read());\n            bis.mark(100);\n            for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {\n                System.out.print((char) c + \" \");\n            }\n            System.out.println();\n            bis.reset();\n            for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) {\n                System.out.print((char) c + \" \");\n            }\n            bis.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestBufferStream2.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestBufferStream2 {\n    public static void main(String[] args) {\n        try {\n            BufferedWriter bw = new BufferedWriter(new FileWriter(\"d:\\\\share\\\\java\\\\dat2.txt\"));\n            BufferedReader br = new BufferedReader(new FileReader(\"d:\\\\share\\\\java\\\\dat2.txt\"));\n            String s = null;\n            for (int i = 1; i <= 100; i++) {\n                s = String.valueOf(Math.random());\n                bw.write(s);\n                bw.newLine();\n            }\n            bw.flush();\n            while ((s = br.readLine()) != null) {\n                System.out.println(s);\n            }\n            bw.close();\n            br.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestDataStream.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestDataStream {\n    public static void main(String[] args) {\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        DataOutputStream dos = new DataOutputStream(baos);\n        try {\n            dos.writeDouble(Math.random());\n            dos.writeBoolean(true);\n            ByteArrayInputStream bais =\n                    new ByteArrayInputStream(baos.toByteArray());\n            System.out.println(bais.available());\n            DataInputStream dis = new DataInputStream(bais);\n            System.out.println(dis.readDouble());\n            System.out.println(dis.readBoolean());\n            dos.close();\n            dis.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestFileInputStream.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestFileInputStream {\n    public static void main(String[] args) {\n        int b = 0;\n        FileInputStream in = null;\n        try {\n            in = new FileInputStream(\"d:\\\\share\\\\java\\\\io\\\\TestFileInputStream.java\");\n        } catch (FileNotFoundException e) {\n            System.out.println(\"找不到指定的文件\");\n            System.exit(-1);\n        }\n\n        try {\n            long num = 0;\n            while ((b = in.read()) != -1) {\n                System.out.print((char) b);\n                num++;\n            }\n            in.close();\n            System.out.println();\n            System.out.println(\"共读取了 \" + num + \" 个字节\");\n        } catch (IOException e1) {\n            System.out.println(\"文件读取错误\");\n            System.exit(-1);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestFileOutputStream.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestFileOutputStream {\n    public static void main(String[] args) {\n        int b = 0;\n        FileInputStream in = null;\n        FileOutputStream out = null;\n        try {\n            in = new FileInputStream(\"d:/share/java/HelloWorld.java\");\n            out = new FileOutputStream(\"d:/share/java/io/HW.java\");\n            while ((b = in.read()) != -1) {\n                out.write(b);\n            }\n            in.close();\n            out.close();\n        } catch (FileNotFoundException e2) {\n            System.out.println(\"找不到指定文件\");\n            System.exit(-1);\n        } catch (IOException e1) {\n            System.out.println(\"文件复制错误\");\n            System.exit(-1);\n        }\n        System.out.println(\"文件已复制\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestFileReader.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestFileReader {\n    public static void main(String[] args) {\n        FileReader fr = null;\n        int c = 0;\n        try {\n            fr = new FileReader(\"d:\\\\share\\\\java\\\\io\\\\TestFileReader.java\");\n            int ln = 0;\n            while ((c = fr.read()) != -1) {\n                //char ch = (char) fr.read();\n                System.out.print((char) c);\n                //if (++ln >= 100) { System.out.println(); ln = 0;}\n            }\n            fr.close();\n        } catch (FileNotFoundException e) {\n            System.out.println(\"找不到指定文件\");\n        } catch (IOException e) {\n            System.out.println(\"文件读取错误\");\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestFileWriter.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestFileWriter {\n    public static void main(String[] args) {\n        FileWriter fw = null;\n        try {\n            fw = new FileWriter(\"d:\\\\bak\\\\unicode.dat\");\n            for (int c = 0; c <= 50000; c++) {\n                fw.write(c);\n            }\n            fw.close();\n        } catch (IOException e1) {\n            e1.printStackTrace();\n            System.out.println(\"文件写入错误\");\n            System.exit(-1);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestFileWriter2.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestFileWriter2 {\n    public static void main(String[] args) throws Exception {\n        FileReader fr = new FileReader(\"d:/java/io/TestFileWriter2.java\");\n        FileWriter fw = new FileWriter(\"d:/java/io/TestFileWriter2.bak\");\n        int b;\n        while ((b = fr.read()) != -1) {\n            fw.write(b);\n        }\n        fr.close();\n        fw.close();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestObjectIO.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestObjectIO {\n    public static void main(String args[]) throws Exception {\n        T t = new T();\n        t.k = 8;\n        FileOutputStream fos = new FileOutputStream(\"d:/share/java/io/testobjectio.dat\");\n        ObjectOutputStream oos = new ObjectOutputStream(fos);\n        oos.writeObject(t);\n        oos.flush();\n        oos.close();\n\n        FileInputStream fis = new FileInputStream(\"d:/share/java/io/testobjectio.dat\");\n        ObjectInputStream ois = new ObjectInputStream(fis);\n        T tReaded = (T) ois.readObject();\n        System.out.println(tReaded.i + \" \" + tReaded.j + \" \" + tReaded.d + \" \" + tReaded.k);\n    }\n}\n\nclass T implements Serializable {\n    int i = 10;\n    int j = 9;\n    double d = 2.3;\n    transient int k = 15;\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestPrintStream1.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestPrintStream1 {\n    public static void main(String[] args) {\n        PrintStream ps = null;\n        try {\n            FileOutputStream fos = new FileOutputStream(\"d:\\\\bak\\\\log.dat\");\n            ps = new PrintStream(fos);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        if (ps != null) {\n            System.setOut(ps);\n        }\n        int ln = 0;\n        for (char c = 0; c <= 60000; c++) {\n            System.out.print(c + \" \");\n            if (ln++ >= 100) {\n                System.out.println();\n                ln = 0;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestPrintStream2.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestPrintStream2 {\n    public static void main(String[] args) {\n        String filename = args[0];\n        if (filename != null) {\n            list(filename, System.out);\n        }\n    }\n\n    public static void list(String f, PrintStream fs) {\n        try {\n            BufferedReader br = new BufferedReader(new FileReader(f));\n            String s = null;\n            while ((s = br.readLine()) != null) {\n                fs.println(s);\n            }\n            br.close();\n        } catch (IOException e) {\n            fs.println(e);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestPrintStream3.java",
    "content": "package com.basic.chapter0700;\n\nimport java.util.*;\nimport java.io.*;\n\npublic class TestPrintStream3 {\n    public static void main(String[] args) {\n        String s = null;\n        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));\n        try {\n            FileWriter fw = new FileWriter(\"d:\\\\bak\\\\logfile.log\", true); //Log4J\n            PrintWriter log = new PrintWriter(fw);\n            while ((s = br.readLine()) != null) {\n                if (s.equalsIgnoreCase(\"exit\")) break;\n                System.out.println(s.toUpperCase());\n                log.println(\"-----\");\n                log.println(s.toUpperCase());\n                log.flush();\n            }\n            log.println(\"===\" + new Date() + \"===\");\n            log.flush();\n            log.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestTransForm1.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestTransForm1 {\n    public static void main(String[] args) {\n        try {\n            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(\"d:\\\\bak\\\\char.txt\"));\n            osw.write(\"mircosoftibmsunapplehp\");\n            System.out.println(osw.getEncoding());\n            osw.close();\n            osw = new OutputStreamWriter(new FileOutputStream(\"d:\\\\bak\\\\char.txt\", true), \"ISO8859_1\"); // latin-1\n            osw.write(\"mircosoftibmsunapplehp\");\n            System.out.println(osw.getEncoding());\n            osw.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TestTransForm2.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TestTransForm2 {\n    public static void main(String args[]) {\n        InputStreamReader isr = new InputStreamReader(System.in);\n        BufferedReader br = new BufferedReader(isr);\n        String s = null;\n        try {\n            s = br.readLine();\n            while (s != null) {\n                if (s.equalsIgnoreCase(\"exit\")) break;\n                System.out.println(s.toUpperCase());\n                s = br.readLine();\n            }\n            br.close();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n} // 阻塞"
  },
  {
    "path": "src/main/java/com/basic/chapter0700/TreeDir.java",
    "content": "package com.basic.chapter0700;\n\nimport java.io.*;\n\npublic class TreeDir {\n    public static void main(String[] args) {\n        listF(new File(\"d:/test\"), 0);\n    }\n\n    public static void listF(File f, int level) {\n        String preStr = \"\";\n        for (int i = 0; i < level; i++) preStr += \"    \";\n        System.out.println(preStr + f.getName());\n        if (f.isDirectory()) {\n            File[] files = f.listFiles();\n            for (File cf : files) listF(cf, level + 1);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/111.txt",
    "content": "1 2 3 4 5 \n6 7 8 9 10 \n11 12 13 14 15 \n16 17 18 19 20 \n21 22 23 24 25 \n"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/ProducerConsumer.java",
    "content": "package com.basic.chapter0800;\n\npublic class ProducerConsumer {\n\tpublic static void main(String[] args) {\n\t\tSyncStack ss = new SyncStack();\n\t\tProducer p = new Producer(ss);\n\t\tConsumer c = new Consumer(ss);\n\t\tnew Thread(p).start();\n\t\tnew Thread(p).start();\n\t\tnew Thread(p).start();\n\t\tnew Thread(c).start();\n\t}\n}\n\nclass WoTou {\n\tint id; \n\tWoTou(int id) {\n\t\tthis.id = id;\n\t}\n\tpublic String toString() {\n\t\treturn \"WoTou : \" + id;\n\t}\n}\n\nclass SyncStack {\n\tint index = 0;\n\tWoTou[] arrWT = new WoTou[6];\n\t\n\tpublic synchronized void push(WoTou wt) {\n\t\twhile(index == arrWT.length) {\n\t\t\ttry {\n\t\t\t\tthis.wait();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\tthis.notifyAll();\t// 叫醒所有在该对象上的线程\n\t\tarrWT[index] = wt;\n\t\tindex ++;\n\t}\n\t\n\tpublic synchronized WoTou pop() {\n\t\twhile(index == 0) {\n\t\t\ttry {\n\t\t\t\tthis.wait();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\tthis.notifyAll();\n\t\tindex--;\n\t\treturn arrWT[index];\n\t}\n}\n\nclass Producer implements Runnable {\n\tSyncStack ss = null;\n\tProducer(SyncStack ss) {\n\t\tthis.ss = ss;\n\t}\n\t\n\tpublic void run() {\n\t\tfor(int i=0; i<20; i++) {\n\t\t\tWoTou wt = new WoTou(i);\n\t\t\tss.push(wt);\nSystem.out.println(\"生产了：\" + wt);\n\t\t\ttry {\n\t\t\t\tThread.sleep((int)(Math.random() * 200));\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\t\t\t\n\t\t}\n\t}\n}\n\nclass Consumer implements Runnable {\n\tSyncStack ss = null;\n\tConsumer(SyncStack ss) {\n\t\tthis.ss = ss;\n\t}\n\t\n\tpublic void run() {\n\t\tfor(int i=0; i<20; i++) {\n\t\t\tWoTou wt = ss.pop();\nSystem.out.println(\"消费了: \" + wt);\n\t\t\ttry {\n\t\t\t\tThread.sleep((int)(Math.random() * 1000));\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\t\t\t\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/ProducerConsumer2.java",
    "content": "package com.basic.chapter0800;\n\npublic class ProducerConsumer2 {\n    public static void main(String args[]) {\n        SyncStack2 stack = new SyncStack2();\n        Runnable p = new Producer2(stack);\n        Runnable c = new Consumer2(stack);\n        Thread t1 = new Thread(p);\n        Thread t2 = new Thread(c);\n        t1.start();\n        t2.start();\n    }\n}\n\n\nclass SyncStack2 {\n    private int index = 0;\n    private char[] data = new char[6];\n\n    public synchronized void push(char c) {\n        if (index == data.length) {\n            try {\n                this.wait();\n            } catch (InterruptedException e) {\n            }\n        }\n        this.notify();\n        data[index] = c;\n        index++;\n    }\n\n    public synchronized char pop() {\n        if (index == 0) {\n            try {\n                this.wait();\n            } catch (InterruptedException e) {\n            }\n        }\n        this.notify();\n        index--;\n        return data[index];\n    }\n}\n\n\nclass Producer2 implements Runnable {\n    SyncStack2 stack;\n\n    public Producer2(SyncStack2 s) {\n        stack = s;\n    }\n\n    public void run() {\n        for (int i = 0; i < 20; i++) {\n            char c = (char) (Math.random() * 26 + 'A');\n            stack.push(c);\n            System.out.println(\"produced: \" + c);\n            try {\n                Thread.sleep((int) (Math.random() * 1000));\n            } catch (InterruptedException e) {\n            }\n        }\n    }\n}\n\n\nclass Consumer2 implements Runnable {\n    SyncStack2 stack;\n\n    public Consumer2(SyncStack2 s) {\n        stack = s;\n    }\n\n    public void run() {\n        for (int i = 0; i < 20; i++) {\n            char c = stack.pop();\n            System.out.println(\"consumed: \" + c);\n            try {\n                Thread.sleep((int) (Math.random() * 1000));\n            } catch (InterruptedException e) {\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/RecursiveFile.java",
    "content": "package com.basic.chapter0800;\n\npublic class RecursiveFile {\n    public static void main(String[] args) {\n\n    }\n\n    public static void f() {\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/T.java",
    "content": "package com.basic.chapter0800;\n\npublic class T {\n    public static void main(String[] args) {\n        m1();\n    }\n\n    public static void m1() {\n        m2();\n        m3();\n    }\n\n    public static void m2() {\n    }\n\n    public static void m3() {\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TT.java",
    "content": "package com.basic.chapter0800;\n\npublic class TT implements Runnable {\n    int b = 100;\n\n    public synchronized void m1() throws Exception {\n        //Thread.sleep(2000);\n        b = 1000;\n        Thread.sleep(5000);\n        System.out.println(\"b = \" + b);\n    }\n\n    public synchronized void m2() throws Exception {\n        Thread.sleep(2500);\n        b = 2000;\n    }\n\n    public void run() {\n        try {\n            m1();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    public static void main(String[] args) throws Exception {\n        TT tt = new TT();\n        Thread t = new Thread(tt);\n        t.start();\n\n        tt.m2();\n        System.out.println(tt.b);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/Test.java",
    "content": "package com.basic.chapter0800;\n\nimport java.io.*;\n\npublic class Test {\n    public static void main(String[] args) throws Exception {\n        FileWriter fw = new FileWriter(\"111.txt\");\n        BufferedWriter bw = new BufferedWriter(fw);\n        for (int i = 1; i <= 25; i++) {\n            bw.write(i + \" \");\n            if (i % 5 == 0) bw.newLine();\n        }\n\n        bw.flush();\n        bw.close();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestDeadLock.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestDeadLock implements Runnable {\n\tpublic int flag = 1;\n\tstatic Object o1 = new Object(), o2 = new Object();\n\tpublic void run() {\nSystem.out.println(\"flag=\" + flag);\n\t\tif(flag == 1) {\n\t\t\tsynchronized(o1) {\n\t\t\t\ttry {\n\t\t\t\t\tThread.sleep(500);\n\t\t\t\t} catch (Exception e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tsynchronized(o2) {\n\t\t\t\t\tSystem.out.println(\"1\");\t\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(flag == 0) {\n\t\t\tsynchronized(o2) {\n\t\t\t\ttry {\n\t\t\t\t\tThread.sleep(500);\n\t\t\t\t} catch (Exception e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tsynchronized(o1) {\n\t\t\t\t\tSystem.out.println(\"0\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\t\n\t\n\tpublic static void main(String[] args) {\n\t\tTestDeadLock td1 = new TestDeadLock();\n\t\tTestDeadLock td2 = new TestDeadLock();\n\t\ttd1.flag = 1;\n\t\ttd2.flag = 0;\n\t\tThread t1 = new Thread(td1);\n\t\tThread t2 = new Thread(td2);\n\t\tt1.start();\n\t\tt2.start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestInterrupt.java",
    "content": "package com.basic.chapter0800;\n\nimport java.util.*;\n\npublic class TestInterrupt {\n    public static void main(String[] args) {\n        MyThread thread = new MyThread();\n        thread.start();\n        try {\n            Thread.sleep(10000);\n        } catch (InterruptedException e) {\n        }\n        thread.interrupt();\n    }\n}\n\nclass MyThread extends Thread {\n    boolean flag = true;\n\n    public void run() {\n        while (flag) {\n            System.out.println(\"===\" + new Date() + \"===\");\n            try {\n                sleep(1000);\n            } catch (InterruptedException e) {\n                return;\n            }\n        }\n    }\n}\n/*\npublic void run() {\n    while (true) {\n      String temp = new Date().toString();\n      String t = temp.substring(11, temp.indexOf('C'));\n      t = t.trim();\n      String[] time = t.split(\":\");\n      if (time.length == 3) {\n        System.out.println(time[0] + time[1] + time[2]);\n      }\n      try {\n        Thread.sleep(5000);\n      } catch (InterruptedException e) {\n        return;\n      }  \n    }\n  }\n}\n*/"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestJoin.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestJoin {\n    public static void main(String[] args) {\n        MyThread2 t1 = new MyThread2(\"abcde\");\n        t1.start();\n        try {\n            t1.join();\n        } catch (InterruptedException e) {\n        }\n\n        for (int i = 1; i <= 10; i++) {\n            System.out.println(\"i am main thread\");\n        }\n    }\n}\n\nclass MyThread2 extends Thread {\n    MyThread2(String s) {\n        super(s);\n    }\n\n    public void run() {\n        for (int i = 1; i <= 10; i++) {\n            System.out.println(\"i am \" + getName());\n            try {\n                sleep(1000);\n            } catch (InterruptedException e) {\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestPriority.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestPriority {\n    public static void main(String[] args) {\n        Thread t1 = new Thread(new T1());\n        Thread t2 = new Thread(new T2());\n        t1.setPriority(Thread.NORM_PRIORITY + 3);\n        t1.start();\n        t2.start();\n    }\n}\n\nclass T1 implements Runnable {\n    public void run() {\n        for (int i = 0; i < 1000; i++) {\n            System.out.println(\"T1: \" + i);\n        }\n    }\n}\n\nclass T2 implements Runnable {\n    public void run() {\n        for (int i = 0; i < 1000; i++) {\n            System.out.println(\"------T2: \" + i);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestSync.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestSync implements Runnable {\n    Timer timer = new Timer();\n\n    public static void main(String[] args) {\n        TestSync test = new TestSync();\n        Thread t1 = new Thread(test);\n        Thread t2 = new Thread(test);\n        t1.setName(\"t1\");\n        t2.setName(\"t2\");\n        t1.start();\n        t2.start();\n    }\n\n    public void run() {\n        timer.add(Thread.currentThread().getName());\n    }\n}\n\nclass Timer {\n    private static int num = 0;\n\n    public synchronized void add(String name) {\n        // synchronized (this) {\n        num++;\n        try {\n            Thread.sleep(1);\n        } catch (InterruptedException e) {\n        }\n        System.out.println(name + \", \" + num);\n        // }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestThread1.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestThread1 {\n    public static void main(String args[]) {\n        Runner1 r = new Runner1();\n        r.start();\n        //r.run();\n        //Thread t = new Thread(r);\n        //t.start();\n\n        for (int i = 0; i < 100; i++) {\n            System.out.println(\"Main Thread:------\" + i);\n        }\n    }\n}\n\n//class Runner1 implements Runnable {\nclass Runner1 extends Thread {\n    public void run() {\n        for (int i = 0; i < 100; i++) {\n            System.out.println(\"Runner1 :\" + i);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestThread2.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestThread2 {\n    public static void main(String args[]) {\n        Runner2 r = new Runner2();\n        Thread t1 = new Thread(r);\n        Thread t2 = new Thread(r);\n        t1.start();\n        t2.start();\n    }\n}\n\nclass Runner2 implements Runnable {\n    public void run() {\n        for (int i = 0; i < 30; i++) {\n            System.out.println(\"No. \" + i);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestThread3.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestThread3 {\n    public static void main(String args[]) {\n        Runner3 r = new Runner3();\n        Thread t = new Thread(r);\n        t.start();\n    }\n}\n\nclass Runner3 implements Runnable {\n    public void run() {\n        for (int i = 0; i < 30; i++) {\n            if (i % 10 == 0 && i != 0) {\n                try {\n                    Thread.sleep(2000);\n                } catch (InterruptedException e) {\n                }\n            }\n            System.out.println(\"No. \" + i);\n        }\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestThread4.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestThread4 {\n    public static void main(String args[]) {\n        Runner4 r = new Runner4();\n        Thread t = new Thread(r);\n        t.start();\n        for (int i = 0; i < 100000; i++) {\n            if (i % 10000 == 0 & i > 0)\n                System.out.println(\"in thread main i=\" + i);\n        }\n        System.out.println(\"Thread main is over\");\n        r.shutDown();\n        //t.stop();\n    }\n}\n\nclass Runner4 implements Runnable {\n    private boolean flag = true;\n\n    public void run() {\n        int i = 0;\n        while (flag == true) {\n            System.out.print(\" \" + i++);\n        }\n    }\n\n    public void shutDown() {\n        flag = false;\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestThread5.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestThread5 {\n\tpublic static void main(String args[]){\n\t\tRunner5 r = new Runner5();\n       \tThread t = new Thread(r);\n        t.start();\n        \n        try{\n        \tt.join();\n        }catch(InterruptedException e){\n        }\n        \n        for(int i=0;i<50;i++){\n        \tSystem.out.println(\"main thread:\" + i);\n        }\n    }\n}\n\nclass Runner5 implements Runnable {\n\tpublic void run() {\n\t\tfor(int i=0;i<50;i++) {\n\t\t\tSystem.out.println(\"SubThread: \" + i);\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestThread6.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestThread6 {\n    public static void main(String args[]) {\n        Thread t = new Runner6();\n        t.start();\n\n        for (int i = 0; i < 50; i++) {\n            System.out.println(\"MainThread: \" + i);\n        }\n    }\n}\n\nclass Runner6 extends Thread {\n    public void run() {\n        System.out.println(Thread.currentThread().isAlive());\n        for (int i = 0; i < 50; i++) {\n            System.out.println(\"SubThread: \" + i);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0800/TestYield.java",
    "content": "package com.basic.chapter0800;\n\npublic class TestYield {\n    public static void main(String[] args) {\n        MyThread3 t1 = new MyThread3(\"t1\");\n        MyThread3 t2 = new MyThread3(\"t2\");\n        t1.start();\n        t2.start();\n    }\n}\n\nclass MyThread3 extends Thread {\n    MyThread3(String s) {\n        super(s);\n    }\n\n    public void run() {\n        for (int i = 1; i <= 100; i++) {\n            System.out.println(getName() + \": \" + i);\n            if (i % 10 == 0) {\n                yield();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chapter0901TestUDPClient.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\n\npublic class Chapter0901TestUDPClient {\n    public static void main(String args[]) throws Exception {\n        byte[] buf = \"Hello\".getBytes();\n        DatagramPacket dp = new DatagramPacket(buf, buf.length, new InetSocketAddress(\"127.0.0.1\", 5678));\n        DatagramSocket ds = new DatagramSocket(9999);\n        ds.send(dp);\n        ds.close();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chapter0901TestUDPServer.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\n\npublic class Chapter0901TestUDPServer {\n    public static void main(String args[]) throws Exception {\n        byte buf[] = new byte[1024];\n        DatagramPacket dp = new DatagramPacket(buf, buf.length);\n        DatagramSocket ds = new DatagramSocket(5678);\n        while (true) {\n            ds.receive(dp);\n            System.out.println(new String(buf, 0, dp.getLength()));\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat03/ChatClient.java",
    "content": "package com.basic.chapter0900.Chat.Chat03;\n\nimport java.io.*;\nimport java.net.*;\n\npublic class ChatClient {\n    Socket s = null;\n\n    public ChatClient() throws Exception {\n        s = new Socket(\"127.0.0.1\", 8888);\n    }\n\n    public void send(String str) throws Exception {\n        DataOutputStream dos = new DataOutputStream(s.getOutputStream());\n        dos.writeUTF(str);\n    }\n\n    public void disconnect() throws Exception {\n        s.close();\n    }\n\n    public static void main(String[] args) throws Exception {\n        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));\n        ChatClient cc = new ChatClient();\n        String str = br.readLine();\n        while (str != null && str.length() != 0) {\n            cc.send(str);\n            str = br.readLine();\n        }\n        cc.disconnect();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat03/ChatServer.java",
    "content": "package com.basic.chapter0900.Chat.Chat03;\n\nimport java.net.*;\nimport java.util.*;\nimport java.io.*;\n\npublic class ChatServer {\n    ServerSocket server = null;\n    Collection cClient = new ArrayList();\n\n    public ChatServer(int port) throws Exception {\n        server = new ServerSocket(port);\n    }\n\n    public void startServer() throws Exception {\n        while (true) {\n            Socket s = server.accept();\n            cClient.add(new ClientConn(s));\n        }\n    }\n\n    class ClientConn implements Runnable {\n        Socket s = null;\n\n        public ClientConn(Socket s) {\n            this.s = s;\n            (new Thread(this)).start();\n        }\n\n        public void run() {\n            try {\n                DataInputStream dis = new DataInputStream(s.getInputStream());\n                String str = dis.readUTF();\n                while (str != null && str.length() != 0) {\n                    System.out.println(str);\n                    str = dis.readUTF();\n                }\n                s.close();\n                cClient.remove(this);\n            } catch (IOException e) {\n                System.out.println(\"client quit\");\n                try {\n                    if (s != null)\n                        s.close();\n                    cClient.remove(this);\n                } catch (IOException ioe) {\n                    ioe.printStackTrace();\n                }\n            }\n        }\n    }\n\n    public static void main(String[] args) throws Exception {\n        ChatServer cs = new ChatServer(8888);\n        cs.startServer();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat05/ChatClient.java",
    "content": "package com.basic.chapter0900.Chat.Chat05;\n\nimport java.io.*;\nimport java.net.*;\n\npublic class ChatClient {\n    Socket s = null;\n\n    public ChatClient() throws Exception {\n        s = new Socket(\"127.0.0.1\", 8888);\n        (new Thread(new ReceiveThread())).start();\n    }\n\n    public void send(String str) throws Exception {\n        DataOutputStream dos = new DataOutputStream(s.getOutputStream());\n        dos.writeUTF(str);\n    }\n\n    public void disconnect() throws Exception {\n        s.close();\n    }\n\n    public static void main(String[] args) throws Exception {\n        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));\n        ChatClient cc = new ChatClient();\n        String str = br.readLine();\n        while (str != null && str.length() != 0) {\n            cc.send(str);\n            str = br.readLine();\n        }\n        cc.disconnect();\n    }\n\n    class ReceiveThread implements Runnable {\n        public void run() {\n            if (s == null) return;\n            try {\n                DataInputStream dis = new DataInputStream(s.getInputStream());\n                String str = dis.readUTF();\n                while (str != null && str.length() != 0) {\n                    System.out.println(str);\n                    str = dis.readUTF();\n                }\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat05/ChatServer.java",
    "content": "package com.basic.chapter0900.Chat.Chat05;\n\nimport java.net.*;\nimport java.util.*;\nimport java.io.*;\n\npublic class ChatServer {\n    ServerSocket server = null;\n    Collection cClient = new ArrayList();\n\n    public ChatServer(int port) throws Exception {\n        server = new ServerSocket(port);\n    }\n\n    public void startServer() throws Exception {\n        while (true) {\n            Socket s = server.accept();\n            cClient.add(new ClientConn(s));\n        }\n    }\n\n    class ClientConn implements Runnable {\n        Socket s = null;\n\n        public ClientConn(Socket s) {\n            this.s = s;\n            (new Thread(this)).start();\n        }\n\n        public void send(String str) throws IOException {\n            DataOutputStream dos = new DataOutputStream(s.getOutputStream());\n            dos.writeUTF(str);\n        }\n\n        public void run() {\n            try {\n                DataInputStream dis = new DataInputStream(s.getInputStream());\n                String str = dis.readUTF();\n                while (str != null && str.length() != 0) {\n                    System.out.println(str);\n                    for (Iterator it = cClient.iterator(); it.hasNext(); ) {\n                        ClientConn cc = (ClientConn) it.next();\n                        if (this != cc) {\n                            cc.send(str);\n                        }\n                    }\n                    str = dis.readUTF();\n                    //send(str);\n                }\n                s.close();\n                cClient.remove(this);\n            } catch (IOException e) {\n                System.out.println(\"client quit\");\n                try {\n                    if (s != null)\n                        s.close();\n                    cClient.remove(this);\n                } catch (IOException ioe) {\n                    ioe.printStackTrace();\n                }\n            }\n        }\n    }\n\n    public static void main(String[] args) throws Exception {\n        ChatServer cs = new ChatServer(8888);\n        cs.startServer();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat07/ChatClient.java",
    "content": "package com.basic.chapter0900.Chat.Chat07;\n\nimport java.io.*;\nimport java.net.*;\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class ChatClient extends Frame {\n    TextArea ta = new TextArea();\n    TextField tf = new TextField();\n\n    public void launchFrame() throws Exception {\n        this.add(ta, BorderLayout.CENTER);\n        this.add(tf, BorderLayout.SOUTH);\n        tf.addActionListener((ActionEvent ae) -> {\n\t\t\ttry {\n\t\t\t\tString sSend = tf.getText();\n\t\t\t\tif (sSend.trim().length() == 0) return;\n\t\t\t\tChatClient.this.send(sSend);\n\t\t\t\ttf.setText(\"\");\n\t\t\t\tta.append(sSend + \"\\n\");\n\t\t\t} catch (Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t});\n\n        setBounds(300, 300, 300, 400);\n        setVisible(true);\n        tf.requestFocus();\n    }\n\n    Socket s = null;\n\n    public ChatClient() throws Exception {\n        s = new Socket(\"127.0.0.1\", 8888);\n        launchFrame();\n        (new Thread(new ReceiveThread())).start();\n    }\n\n    public void send(String str) throws Exception {\n        DataOutputStream dos = new DataOutputStream(s.getOutputStream());\n        dos.writeUTF(str);\n    }\n\n    public void disconnect() throws Exception {\n        s.close();\n    }\n\n    public static void main(String[] args) throws Exception {\n        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));\n        ChatClient cc = new ChatClient();\n        String str = br.readLine();\n        while (str != null && str.length() != 0) {\n            cc.send(str);\n            str = br.readLine();\n        }\n        cc.disconnect();\n    }\n\n    class ReceiveThread implements Runnable {\n        public void run() {\n            if (s == null) return;\n            try {\n                DataInputStream dis = new DataInputStream(s.getInputStream());\n                String str = dis.readUTF();\n                while (str != null && str.length() != 0) {\n                    // System.out.println(str);\n                    ChatClient.this.ta.append(str + \"\\n\");\n                    str = dis.readUTF();\n                }\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat07/ChatServer.java",
    "content": "package com.basic.chapter0900.Chat.Chat07;\n\nimport java.net.*;\nimport java.util.*;\nimport java.io.*;\n\npublic class ChatServer {\n    ServerSocket server = null;\n    Collection cClient = new ArrayList();\n\n    public ChatServer(int port) throws Exception {\n        server = new ServerSocket(port);\n    }\n\n    public void startServer() throws Exception {\n        while (true) {\n            Socket s = server.accept();\n            cClient.add(new ClientConn(s));\n        }\n    }\n\n    class ClientConn implements Runnable {\n        Socket s = null;\n\n        public ClientConn(Socket s) {\n            this.s = s;\n            (new Thread(this)).start();\n        }\n\n        public void send(String str) throws IOException {\n            DataOutputStream dos = new DataOutputStream(s.getOutputStream());\n            dos.writeUTF(str);\n        }\n\n        public void run() {\n            try {\n\n                DataInputStream dis = new DataInputStream(s.getInputStream());\n                String str = dis.readUTF();\n                while (str != null && str.length() != 0) {\n                    System.out.println(str);\n                    for (Iterator it = cClient.iterator(); it.hasNext(); ) {\n                        ClientConn cc = (ClientConn) it.next();\n                        if (this != cc) {\n                            cc.send(str);\n                        }\n                    }\n                    str = dis.readUTF();\n                    //send(str);\n                }\n                s.close();\n                cClient.remove(this);\n            } catch (IOException e) {\n                System.out.println(\"client quit\");\n                try {\n                    if (s != null)\n                        s.close();\n                    cClient.remove(this);\n                } catch (IOException ioe) {\n                    ioe.printStackTrace();\n                }\n            }\n        }\n    }\n\n    public static void main(String[] args) throws Exception {\n        ChatServer cs = new ChatServer(8888);\n        cs.startServer();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat10/ChatClient.java",
    "content": "package com.basic.chapter0900.Chat.Chat10;\n\nimport java.io.*;\nimport java.net.*;\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class ChatClient extends Frame {\n    TextArea ta = new TextArea();\n    TextField tf = new TextField();\n\n    public void launchFrame() throws Exception {\n        this.add(ta, BorderLayout.CENTER);\n        this.add(tf, BorderLayout.SOUTH);\n        tf.addActionListener((ActionEvent ae) -> {\n\t\t\ttry {\n\t\t\t\tString sSend = tf.getText();\n\t\t\t\tif (sSend.trim().length() == 0) return;\n\t\t\t\tChatClient.this.send(sSend);\n\t\t\t\ttf.setText(\"\");\n\t\t\t\tta.append(sSend + \"\\n\");\n\t\t\t} catch (Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t});\n\n        this.addWindowListener(\n                new WindowAdapter() {\n                    public void windowClosing(WindowEvent e) {\n                        System.exit(0);\n                    }\n                }\n        );\n        setBounds(300, 300, 300, 400);\n        setVisible(true);\n        tf.requestFocus();\n    }\n\n    Socket s = null;\n\n    public ChatClient() throws Exception {\n        s = new Socket(\"127.0.0.1\", 8888);\n        launchFrame();\n        (new Thread(new ReceiveThread())).start();\n    }\n\n    public void send(String str) throws Exception {\n        DataOutputStream dos = new DataOutputStream(s.getOutputStream());\n        dos.writeUTF(str);\n    }\n\n    public void disconnect() throws Exception {\n        s.close();\n    }\n\n    public static void main(String[] args) throws Exception {\n        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));\n        ChatClient cc = new ChatClient();\n        String str = br.readLine();\n        while (str != null && str.length() != 0) {\n            cc.send(str);\n            str = br.readLine();\n        }\n        cc.disconnect();\n    }\n\n    class ReceiveThread implements Runnable {\n        public void run() {\n            if (s == null) return;\n            try {\n                DataInputStream dis = new DataInputStream(s.getInputStream());\n                String str = dis.readUTF();\n                while (str != null && str.length() != 0) {\n                    //System.out.println(str);\n                    ChatClient.this.ta.append(str + \"\\n\");\n                    str = dis.readUTF();\n                }\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/Chat/Chat10/ChatServer.java",
    "content": "package com.basic.chapter0900.Chat.Chat10;\n\nimport java.net.*;\nimport java.util.*;\nimport java.io.*;\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class ChatServer extends Frame {\n    TextArea ta = new TextArea();\n\n    public void launchFrame() {\n        add(ta, BorderLayout.CENTER);\n        setBounds(0, 0, 200, 300);\n        this.addWindowListener(\n                new WindowAdapter() {\n                    public void windowClosing(WindowEvent e) {\n                        System.exit(0);\n                    }\n                }\n        );\n        setVisible(true);\n    }\n\n    ServerSocket server = null;\n    Collection cClient = new ArrayList();\n\n    public ChatServer(int port) throws Exception {\n        server = new ServerSocket(port);\n        launchFrame();\n    }\n\n    public void startServer() throws Exception {\n        while (true) {\n            Socket s = server.accept();\n            cClient.add(new ClientConn(s));\n            ta.append(\"NEW-CLIENT \" + s.getInetAddress() + \":\" + s.getPort());\n            ta.append(\"\\n\" + \"CLIENTS-COUNT: \" + cClient.size() + \"\\n\\n\");\n        }\n    }\n\n    class ClientConn implements Runnable {\n        Socket s = null;\n\n        public ClientConn(Socket s) {\n            this.s = s;\n            (new Thread(this)).start();\n        }\n\n        public void send(String str) throws IOException {\n            DataOutputStream dos = new DataOutputStream(s.getOutputStream());\n            dos.writeUTF(str);\n        }\n\n        public void dispose() {\n            try {\n                if (s != null) s.close();\n                cClient.remove(this);\n                ta.append(\"A client out! \\n\");\n                ta.append(\"CLIENT-COUNT: \" + cClient.size() + \"\\n\\n\");\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n\n        public void run() {\n            try {\n                DataInputStream dis = new DataInputStream(s.getInputStream());\n                String str = dis.readUTF();\n                while (str != null && str.length() != 0) {\n                    System.out.println(str);\n                    for (Iterator it = cClient.iterator(); it.hasNext(); ) {\n                        ClientConn cc = (ClientConn) it.next();\n                        if (this != cc) {\n                            cc.send(str);\n                        }\n                    }\n                    str = dis.readUTF();\n                    //send(str);\n                }\n                this.dispose();\n            } catch (Exception e) {\n                System.out.println(\"client quit\");\n                this.dispose();\n            }\n        }\n    }\n\n    public static void main(String[] args) throws Exception {\n        ChatServer cs = new ChatServer(8888);\n        cs.startServer();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TCPClient.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\nimport java.io.*;\n\npublic class TCPClient {\n\tpublic static void main(String[] args) throws Exception {\n\t\tSocket s = new Socket(\"127.0.0.1\", 6666);\n\t\tOutputStream os = s.getOutputStream();\n\t\tDataOutputStream dos = new DataOutputStream(os);\n\t\tThread.sleep(30000);\n\t\tdos.writeUTF(\"hello server!\");\n\t\tdos.flush();\n\t\tdos.close();\n\t\ts.close();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TCPServer.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\nimport java.io.*;\n\npublic class TCPServer {\n\tpublic static void main(String[] args) throws Exception {\n\t\tServerSocket ss = new ServerSocket(6666);\n\t\twhile(true) {\n\t\t\tSocket s = ss.accept();\nSystem.out.println(\"a client connect!\");\n\t\t\tDataInputStream dis = new DataInputStream(s.getInputStream());\n\t\t\tSystem.out.println(dis.readUTF());\n\t\t\tdis.close();\n\t\t\ts.close();\n\t\t}\n\t\t\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TalkClient.java",
    "content": "package com.basic.chapter0900;\n\nimport java.io.*;\nimport java.net.*;\n\npublic class TalkClient {\n    public static void main(String args[]) {\n        try {\n            Socket socket = new Socket(\"127.0.0.1\", 4700);\n            BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));\n            PrintWriter os = new PrintWriter(socket.getOutputStream());\n            BufferedReader is = new BufferedReader(new InputStreamReader(\n                    socket.getInputStream()));\n            String readline;\n            readline = sin.readLine();\n            while (!readline.equals(\"bye\")) {\n                os.println(readline);\n                os.flush();\n                System.out.println(\"Client:\" + readline);\n                System.out.println(\"Server:\" + is.readLine());\n                readline = sin.readLine();\n            }\n            os.close();\n            is.close();\n            socket.close();\n        } catch (Exception e) {\n            System.out.println(\"Error\" + e);\n        }\n    }\n}\n\t\t\t"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TalkServer.java",
    "content": "package com.basic.chapter0900;\n\nimport java.io.*;\nimport java.net.*;\nimport java.applet.Applet;\n\npublic class TalkServer {\n    public static void main(String args[]) {\n        try {\n            ServerSocket server = null;\n            try {\n                server = new ServerSocket(4700);\n            } catch (Exception e) {\n                System.out.println(\"can not listen to:\" + e);\n            }\n            Socket socket = null;\n            try {\n                socket = server.accept();\n            } catch (Exception e) {\n                System.out.println(\"Error:\" + e);\n            }\n            String line;\n            BufferedReader is = new BufferedReader(new InputStreamReader(\n                    socket.getInputStream()));\n            PrintWriter os = new PrintWriter(socket.getOutputStream());\n            BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));\n            System.out.println(\"Client:\" + is.readLine());\n            line = sin.readLine();\n            while (!line.equals(\"bye\")) {\n                os.println(line);\n                os.flush();\n                System.out.println(\"Server:\" + line);\n                System.out.println(\"Client:\" + is.readLine());\n                line = sin.readLine();\n            }\n\n            is.close();\n            os.close();\n            socket.close();\n            server.close();\n        } catch (Exception e) {\n            System.out.println(\"Error\" + e);\n        }\n    }\n}\n\t\t\t"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TestClient.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\nimport java.io.*;\n\npublic class TestClient {\n\tpublic static void main(String args[]) {\n\t\ttry {\n\t\t\tSocket s1 = new Socket(\"127.0.0.1\", 8888);\n\t\t\tInputStream is = s1.getInputStream();\n\t\t\tDataInputStream dis = new DataInputStream(is);\n\t\t\tSystem.out.println(dis.readUTF());\n\t\t\tdis.close();\n\t\t\ts1.close();\n\t\t} catch (ConnectException connExc) {\n\t\t\tconnExc.printStackTrace();\n\t\t\tSystem.err.println(\"throw connection exception...\");\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TestServer.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\nimport java.io.*;\n\npublic class TestServer {\n    public static void main(String args[]) {\n        try {\n            ServerSocket s = new ServerSocket(8888);\n            while (true) {\n                Socket s1 = s.accept();\n                OutputStream os = s1.getOutputStream();\n                DataOutputStream dos = new DataOutputStream(os);\n                dos.writeUTF(\"Hello,\" + s1.getInetAddress() +\n                        \"port#\" + s1.getPort() + \"  bye-bye!\");\n                dos.close();\n                s1.close();\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n            System.out.println(\"异常信息:\" + e);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TestSockClient.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\nimport java.io.*;\n\npublic class TestSockClient {\n    public static void main(String[] args) {\n        InputStream is = null;\n        OutputStream os = null;\n        try {\n            Socket socket = new Socket(\"localhost\", 5888);\n            is = socket.getInputStream();\n            os = socket.getOutputStream();\n            DataInputStream dis = new DataInputStream(is);\n            DataOutputStream dos = new DataOutputStream(os);\n            dos.writeUTF(\"hey\");\n            String s = null;\n            if ((s = dis.readUTF()) != null) ;\n            System.out.println(s);\n            dos.close();\n            dis.close();\n            socket.close();\n        } catch (UnknownHostException e) {\n            e.printStackTrace();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TestSockServer.java",
    "content": "package com.basic.chapter0900;\r\rimport java.io.*;\rimport java.net.*;\r\rpublic class TestSockServer {\r    public static void main(String[] args) {\r        InputStream in = null;\r        OutputStream out = null;\r        try {\r            ServerSocket ss = new ServerSocket(5888);\r            Socket socket = ss.accept();\r            in = socket.getInputStream();\r            out = socket.getOutputStream();\r            DataOutputStream dos = new DataOutputStream(out);\r            DataInputStream dis = new DataInputStream(in);\r            String s = null;\r            if ((s = dis.readUTF()) != null) {\r                System.out.println(s);\r                System.out.println(\"from: \" + socket.getInetAddress());\r                System.out.println(\"Port: \" + socket.getPort());\r            }\r            dos.writeUTF(\"你好，世界！\");\r            dis.close();\r            dos.close();\r            socket.close();\r        } catch (IOException e) {\r            e.printStackTrace();\r        }\r    }\r}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TestUDPClient.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\nimport java.io.*;\n\npublic class TestUDPClient {\n    public static void main(String args[]) throws Exception {\n        long n = 10000L;\n        ByteArrayOutputStream baos = new ByteArrayOutputStream();\n        DataOutputStream dos = new DataOutputStream(baos);\n        dos.writeLong(n);\n\n        byte[] buf = baos.toByteArray();\n        System.out.println(buf.length);\n\n        DatagramPacket dp = new DatagramPacket(buf, buf.length,\n                new InetSocketAddress(\"127.0.0.1\", 5678)\n        );\n        DatagramSocket ds = new DatagramSocket(9999);\n        ds.send(dp);\n        ds.close();\n\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/TestUDPServer.java",
    "content": "package com.basic.chapter0900;\n\nimport java.net.*;\nimport java.io.*;\n\npublic class TestUDPServer {\n    public static void main(String args[]) throws Exception {\n        byte buf[] = new byte[1024];\n        DatagramPacket dp = new DatagramPacket(buf, buf.length);\n        DatagramSocket ds = new DatagramSocket(5678);\n        while (true) {\n            ds.receive(dp);\n            ByteArrayInputStream bais = new ByteArrayInputStream(buf);\n            DataInputStream dis = new DataInputStream(bais);\n            System.out.println(dis.readLong());\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/zerocopy/traditonal/TraditionalClient.java",
    "content": "package com.basic.chapter0900.zerocopy.traditonal;\n\nimport java.io.DataOutputStream;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.net.Socket;\nimport java.net.UnknownHostException;\n\npublic class TraditionalClient {\n    public static void main(String[] args) {\n        int port = 2000;\n        String server = \"localhost\";\n        Socket socket = null;\n        String lineToBeSent;\n\n        DataOutputStream output = null;\n        FileInputStream inputStream = null;\n        int ERROR = 1;\n\n        // connect to server\n        try {\n            socket = new Socket(server, port);\n            System.out.println(\"Connected with server \" + socket.getInetAddress() + \":\" + socket.getPort());\n        } catch (UnknownHostException e) {\n            System.out.println(e);\n            System.exit(ERROR);\n        } catch (IOException e) {\n            System.out.println(e);\n            System.exit(ERROR);\n        }\n\n        try {\n            String fname = \"D:\\\\soft\\\\julia-1.4.2-win64.exe\";\n            inputStream = new FileInputStream(fname);\n\n            output = new DataOutputStream(socket.getOutputStream());\n            long start = System.currentTimeMillis();\n            byte[] b = new byte[4096];\n            long read = 0, total = 0;\n            while ((read = inputStream.read(b)) >= 0) {\n                total = total + read;\n                output.write(b);\n            }\n            System.out.println(\"bytes send--\" + total + \" and totaltime--\" + (System.currentTimeMillis() - start));\n        } catch (IOException e) {\n            System.out.println(e);\n        }\n\n        try {\n            output.close();\n            socket.close();\n            inputStream.close();\n        } catch (IOException e) {\n            System.out.println(e);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/zerocopy/traditonal/TraditionalServer.java",
    "content": "package com.basic.chapter0900.zerocopy.traditonal;\n\nimport java.io.DataInputStream;\nimport java.io.IOException;\nimport java.net.ServerSocket;\nimport java.net.Socket;\n\npublic class TraditionalServer {\n    public static void main(String args[]) {\n        int port = 2000;\n        ServerSocket server_socket;\n        DataInputStream input;\n\n        try {\n            server_socket = new ServerSocket(port);\n            System.out.println(\"Server waiting for client on port \" + server_socket.getLocalPort());\n\n            // server infinite loop\n            while (true) {\n                Socket socket = server_socket.accept();\n                System.out.println(\"New connection accepted \" + socket.getInetAddress() + \":\" + socket.getPort());\n                input = new DataInputStream(socket.getInputStream());\n\n                // print received data\n                try {\n                    byte[] byteArray = new byte[4096];\n                    while (true) {\n                        int nread = input.read(byteArray, 0, 4096);\n                        if (0 == nread)\n                            break;\n                    }\n                } catch (IOException e) {\n                    System.out.println(e);\n                }\n\n                // connection closed by client\n                try {\n                    socket.close();\n                    System.out.println(\"Connection closed by client\");\n                } catch (IOException e) {\n                    System.out.println(e);\n                }\n            }\n        } catch (IOException e) {\n            System.out.println(e);\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/zerocopy/transfer/TransferToClient.java",
    "content": "package com.basic.chapter0900.zerocopy.transfer;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.net.InetSocketAddress;\nimport java.net.SocketAddress;\nimport java.nio.channels.FileChannel;\nimport java.nio.channels.SocketChannel;\n\npublic class TransferToClient {\n\n    public static void main(String[] args) throws IOException {\n        TransferToClient sfc = new TransferToClient();\n        sfc.testSendfile();\n    }\n\n    public void testSendfile() throws IOException {\n        String host = \"localhost\";\n        int port = 9026;\n        SocketAddress sad = new InetSocketAddress(host, port);\n        SocketChannel sc = SocketChannel.open();\n        sc.connect(sad);\n        sc.configureBlocking(true);\n\n        String fname = \"D:\\\\soft\\\\julia-1.4.2-win64.exe\";\n        long fsize = 183678375L, sendzise = 4094;\n\n        // FileProposerExample.stuffFile(fname, fsize);\n        FileChannel fc = new FileInputStream(fname).getChannel();\n        long start = System.currentTimeMillis();\n        long nsent = 0, curnset = 0;\n        curnset = fc.transferTo(0, fsize, sc);\n        System.out.println(\n            \"total bytes transferred--\" + curnset + \" and time taken in MS--\" + (System.currentTimeMillis() - start));\n        fc.close();\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter0900/zerocopy/transfer/TransferToServer.java",
    "content": "package com.basic.chapter0900.zerocopy.transfer;\n\nimport java.io.IOException;\nimport java.net.InetSocketAddress;\nimport java.net.ServerSocket;\nimport java.nio.ByteBuffer;\nimport java.nio.channels.ServerSocketChannel;\nimport java.nio.channels.SocketChannel;\n\npublic class TransferToServer {\n    ServerSocketChannel listener = null;\n\n    protected void mySetup() {\n        InetSocketAddress listenAddr = new InetSocketAddress(9026);\n        try {\n            listener = ServerSocketChannel.open();\n            ServerSocket ss = listener.socket();\n            ss.setReuseAddress(true);\n            ss.bind(listenAddr);\n            System.out.println(\"Listening on port : \" + listenAddr.toString());\n        } catch (IOException e) {\n            System.out.println(\"Failed to bind, is port : \" + listenAddr.toString() + \" already in use ? Error Msg : \"\n                + e.getMessage());\n            e.printStackTrace();\n        }\n\n    }\n\n    public static void main(String[] args) {\n        TransferToServer dns = new TransferToServer();\n        dns.mySetup();\n        dns.readData();\n    }\n\n    private void readData() {\n        ByteBuffer dst = ByteBuffer.allocate(4096);\n        try {\n            while (true) {\n                SocketChannel conn = listener.accept();\n                System.out.println(\"Accepted : \" + conn);\n                conn.configureBlocking(true);\n                int nread = 0;\n                while (nread != -1) {\n                    try {\n                        nread = conn.read(dst);\n                    } catch (IOException e) {\n                        e.printStackTrace();\n                        conn.socket().close();\n                        nread = -1;\n                    }\n                    dst.rewind();\n                }\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/AWTDrawing.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class AWTDrawing {\n    private Frame f = new Frame(\" Hello Out There!\");\n    private Panel p = new Panel();\n\tpublic void launchFrame() {\n\t    f.add(p);\n\t    f.setSize( 170,170);\n\t    f.setBackground( Color.blue);\n\t    f.setVisible( true); \n\t    p.setForeground(Color.red);\n\t    Graphics g = p.getGraphics();\n\t    g.drawArc(30,40,50,60,70,80);\n\t    g.fillArc(30,40,50,60,70,80);\n\t}\n\tpublic static void main( String args[]) {\n\t    AWTDrawing guiWindow = new AWTDrawing();\n\t    guiWindow.launchFrame();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/AWTDrawing2.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\nclass SubPanel extends Panel{\n\tpublic void paint(Graphics g){\n\t\tg.drawString(\"this is a drawing test!\",20,20);\t\t\n\t\tg.drawLine(30,60,100,120);\n\t\tg.draw3DRect(60,50,70,30,false);\n\t}\t\n}\n\t\npublic class AWTDrawing2 {\n    private Frame f = new Frame(\" Hello Out There!\");\n    private SubPanel p = new SubPanel();\n\tpublic void launchFrame() {\n\t    f.add(p);\n\t    f.setSize(170,170);\n\t    f.setBackground( new Color(89,145,145));\n\t    f.setVisible( true); \n\t}\n\tpublic static void main( String args[]) {\n\t    AWTDrawing2 guiWindow = new AWTDrawing2();\n\t    guiWindow.launchFrame();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/CenterPanel.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class CenterPanel {\n    public static void main(String args[]) {\n        new MyFrame3(300, 300, 400, 300, Color.BLUE);\n    }\n}\n\nclass MyFrame3 extends Frame {\n    private Panel p;\n\n    MyFrame3(int x, int y, int w, int h, Color c) {\n        super(\"FrameWithPanel\");\n        setLayout(null);\n        setBounds(x, y, w, h);\n        setBackground(c);\n        p = new Panel(null);\n        p.setBounds(w / 4, h / 4, w / 2, h / 2);\n        p.setBackground(Color.YELLOW);\n        add(p);\n        setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/MyMouseAdapter.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.util.*;\n\npublic class MyMouseAdapter {\n    public static void main(String args[]) {\n        new MyFrame(\"drawing...\");\n    }\n}\n\nclass MyFrame extends Frame {\n    ArrayList points = null;\n\n    MyFrame(String s) {\n        super(s);\n        points = new ArrayList();\n        setLayout(null);\n        setBounds(300, 300, 400, 300);\n        this.setBackground(new Color(204, 204, 255));\n        setVisible(true);\n        this.addMouseListener(new Monitor());\n    }\n\n    public void paint(Graphics g) {\n        Iterator i = points.iterator();\n        while (i.hasNext()) {\n            Point p = (Point) i.next();\n            g.setColor(Color.BLUE);\n            g.fillOval(p.x, p.y, 10, 10);\n        }\n    }\n\n    public void addPoint(Point p) {\n        points.add(p);\n    }\n}\n\nclass Monitor extends MouseAdapter {\n    public void mousePressed(MouseEvent e) {\n        MyFrame f = (MyFrame) e.getSource();\n        f.addPoint(new Point(e.getX(), e.getY()));\n        f.repaint();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/MyMouseAdapterGeneric.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.util.*;\n\npublic class MyMouseAdapterGeneric {\n    public static void main(String args[]) {\n        new MyFrame992(\"drawing...\");\n    }\n}\n\nclass MyFrame992 extends Frame {\n    ArrayList<Point> points = null;\n\n    MyFrame992(String s) {\n        super(s);\n        points = new ArrayList<Point>();\n        setLayout(null);\n        setBounds(300, 300, 400, 300);\n        this.setBackground(new Color(204, 204, 255));\n        setVisible(true);\n        this.addMouseListener(new Monitor2());\n    }\n\n    public void paint(Graphics g) {\n        Iterator<Point> i = points.iterator();\n        while (i.hasNext()) {\n            Point p = i.next();\n            g.setColor(Color.BLUE);\n            g.fillOval(p.x, p.y, 10, 10);\n        }\n    }\n\n    public void addPoint(Point p) {\n        points.add(p);\n    }\n}\n\nclass Monitor2 extends MouseAdapter {\n    public void mousePressed(MouseEvent e) {\n        MyFrame992 f = (MyFrame992) e.getSource();\n        f.addPoint(new Point(e.getX(), e.getY()));\n        f.repaint();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/NestedContainer.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class NestedContainer {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"NestedContainer\");\n        Button b0 = new Button(\"display Area\");\n        Panel p = new Panel();\n        p.setLayout(new GridLayout(2, 2));\n        Button b1 = new Button(\"1\");\n        Button b2 = new Button(\"2\");\n        Button b3 = new Button(\"3\");\n        Button b4 = new Button(\"4\");\n        p.add(b1);\n        p.add(b2);\n        p.add(b3);\n        p.add(b4);\n        f.add(b0, \"North\");\n        f.add(p, \"Center\");\n        f.pack();\n        f.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TFActionEvent.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TFActionEvent {\n    /**\n     * @param args\n     */\n    public static void main(String[] args) {\n        new TFFrame();\n    }\n}\n\nclass TFFrame extends Frame {\n    TFFrame() {\n        TextField tf = new TextField();\n        add(tf);\n        tf.addActionListener(new TFActionListener());\n        pack();\n        setVisible(true);\n    }\n}\n\nclass TFActionListener implements ActionListener {\n    public void actionPerformed(ActionEvent e) {\n        TextField tf = (TextField) e.getSource();\n        System.out.println(tf.getText());\n        //tf.setText(\"\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TFMath.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TFMath {\n    public static void main(String[] args) {\n        new TFFrame3().launchFrame();\n    }\n}\n\nclass TFFrame3 extends Frame {\n    TextField num1, num2, num3;\n\n    public void launchFrame() {\n        num1 = new TextField(10);\n        num2 = new TextField(10);\n        num3 = new TextField(15);\n        Label lblPlus = new Label(\"+\");\n        Button btnEqual = new Button(\"=\");\n        btnEqual.addActionListener(new MyMonitor());\n        setLayout(new FlowLayout());\n        add(num1);\n        add(lblPlus);\n        add(num2);\n        add(btnEqual);\n        add(num3);\n        pack();\n        setVisible(true);\n    }\n\n    private class MyMonitor implements ActionListener {\n        public void actionPerformed(ActionEvent e) {\n            int n1 = Integer.parseInt(num1.getText());\n            int n2 = Integer.parseInt(num2.getText());\n            num3.setText(\"\" + (n1 + n2));\n        }\n    }\n\n}\n\n\n//class MyMonitor implements ActionListener {\n//TextField num1, num2, num3;\n\t/*\n\tpublic MyMonitor(TextField num1, TextField num2, TextField num3) {\n\t\tthis.num1 = num1;\n\t\tthis.num2 = num2;\n\t\tthis.num3 = num3;\n\t}\n\t*/\n/*\t\n\tTFFrame tf = null;\n\t\n\tpublic MyMonitor(TFFrame tf) {\n\t\tthis.tf = tf;\n\t}\n\t\n\tpublic void actionPerformed(ActionEvent e) {\n\t\tint n1 = Integer.parseInt(tf.num1.getText());\n\t\tint n2 = Integer.parseInt(tf.num2.getText());\n\t\ttf.num3.setText(\"\" + (n1+n2));\n\t\t\n\t}\n}\n\n*/"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TFMathTest.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TFMathTest extends Frame {\n    TextField num1;\n    TextField num2;\n    TextField sum;\n\n    /**\n     * @param args\n     */\n    public static void main(String[] args) {\n        new TFMathTest().launchFrame();\n    }\n\n    public void launchFrame() {\n        num1 = new TextField();\n        num2 = new TextField();\n        sum = new TextField();\n        num1.setColumns(10);\n        num2.setColumns(10);\n        sum.setColumns(15);\n        setLayout(new FlowLayout());\n        //setSize(500, 30);\n        Label lblPlus = new Label(\"+\");\n        Button btnEqual = new Button(\"=\");\n        btnEqual.addActionListener(new MyListener2(this));\n        add(num1);\n        add(lblPlus);\n        add(num2);\n        add(btnEqual);\n        add(sum);\n        pack();\n        setVisible(true);\n    }\n}\n\nclass MyListener2 implements ActionListener {\n    private TFMathTest tfmt;\n\n    public MyListener2(TFMathTest tfmt) {\n        this.tfmt = tfmt;\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        String s1 = tfmt.num1.getText();\n        String s2 = tfmt.num2.getText();\n        int i1 = Integer.parseInt(s1);\n        int i2 = Integer.parseInt(s2);\n        tfmt.sum.setText(String.valueOf(i1 + i2));\n    }\n}\n\n\n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TFMathTest2.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TFMathTest2 extends Frame {\n    TextField num1;\n    TextField num2;\n    TextField sum;\n\n    /**\n     * @param args\n     */\n    public static void main(String[] args) {\n        new TFMathTest2().launchFrame();\n    }\n\n    public void launchFrame() {\n        num1 = new TextField();\n        num2 = new TextField();\n        sum = new TextField();\n        num1.setColumns(10);\n        num2.setColumns(10);\n        sum.setColumns(15);\n        setLayout(new FlowLayout());\n        //setSize(500, 30);\n        Label lblPlus = new Label(\"+\");\n        Button btnEqual = new Button(\"=\");\n        btnEqual.addActionListener(new MyListener(this));\n        add(num1);\n        add(lblPlus);\n        add(num2);\n        add(btnEqual);\n        add(sum);\n        pack();\n        setVisible(true);\n    }\n}\n\nclass MyListener implements ActionListener {\n    //private TFMathTest2 tfmt;\n\n    private TextField num1, num2, sum;\n\n    public MyListener(TFMathTest2 tfmt) {\n        //this.tfmt = tfmt;\n\t\t/*\n\t\tthis.num1 = tfmt.num1;\n\t\tthis.num2 = tfmt.num2;\n\t\tthis.sum = tfmt.sum;\n\t\t*/\n        this(tfmt.num1, tfmt.num2, tfmt.sum);\n    }\n\n    public MyListener(TextField num1, TextField num2, TextField sum) {\n        this.num1 = num1;\n        this.num2 = num2;\n        this.sum = sum;\n    }\n\n    public void actionPerformed(ActionEvent e) {\n        String s1 = num1.getText();\n        String s2 = num2.getText();\n        int i1 = Integer.parseInt(s1);\n        int i2 = Integer.parseInt(s2);\n        sum.setText(String.valueOf(i1 + i2));\n    }\n}\n\n\n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TFPassword.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TFPassword {\n\n    /**\n     * @param args\n     */\n    public static void main(String[] args) {\n        new TFFrame2();\n    }\n}\n\nclass TFFrame2 extends Frame {\n    TFFrame2() {\n        TextField tf = new TextField();\n        add(tf);\n        tf.addActionListener(new TFActionListener2());\n        tf.setEchoChar('*');\n        pack();\n        setVisible(true);\n    }\n}\n\nclass TFActionListener2 implements ActionListener {\n    public void actionPerformed(ActionEvent e) {\n        TextField tf = (TextField) e.getSource();\n        System.out.println(tf.getText());\n        tf.setText(\"\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TenButtons.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TenButtons {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"Java Frame\");\n        f.setLayout(new GridLayout(2, 1));\n        f.setLocation(300, 400);\n        f.setSize(300, 200);\n        f.setBackground(new Color(204, 204, 255));\n        Panel p1 = new Panel(new BorderLayout());\n        Panel p2 = new Panel(new BorderLayout());\n        Panel p11 = new Panel(new GridLayout(2, 1));\n        Panel p21 = new Panel(new GridLayout(2, 2));\n        p1.add(new Button(\"BUTTON\"), BorderLayout.WEST);\n        p1.add(new Button(\"BUTTON\"), BorderLayout.EAST);\n        p11.add(new Button(\"BUTTON\"));\n        p11.add(new Button(\"BUTTON\"));\n        p1.add(p11, BorderLayout.CENTER);\n        p2.add(new Button(\"BUTTON\"), BorderLayout.WEST);\n        p2.add(new Button(\"BUTTON\"), BorderLayout.EAST);\n        for (int i = 1; i <= 4; i++) {\n            p21.add(new Button(\"BUTTON\"));\n        }\n        p2.add(p21, BorderLayout.CENTER);\n        f.add(p1);\n        f.add(p2);\n        f.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/Test.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class Test {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"Java Gui\");\n        f.setLayout(null);\n        Button b = new Button(\"Button1\");\n        f.add(b);\n        b.setLocation(47, 70);\n        b.setSize(60, 25);\n        f.setSize(150, 150);\n        f.setBackground(new Color(90, 145, 145, 200));\n        f.setVisible(true);\n    }\n} \n\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestActionEvent.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TestActionEvent {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"Test\");\n        Button b = new Button(\"Press Me!\");\n        Monitor3 bh = new Monitor3();\n        b.addActionListener(bh);\n        f.add(b, BorderLayout.CENTER);\n        f.pack();\n        f.setVisible(true);\n    }\n}\n\nclass Monitor3 implements ActionListener {\n    public void actionPerformed(ActionEvent e) {\n        System.out.println(\"a button has been pressed\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestActionEvent2.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TestActionEvent2 {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"Test\");\n        Button b1 = new Button(\"Start\");\n        Button b2 = new Button(\"Stop\");\n        Monitor6 bh = new Monitor6();\n        b1.addActionListener(bh);\n        b2.addActionListener(bh);\n        b2.setActionCommand(\"game over\");\n        f.add(b1, \"North\");\n        f.add(b2, \"Center\");\n        f.pack();\n        f.setVisible(true);\n    }\n}\n\nclass Monitor6 implements ActionListener {\n    public void actionPerformed(ActionEvent e) {\n        System.out.println(\"a button has been pressed,\" +\n                \"the relative info is:\\n \" + e.getActionCommand());\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestAnonymous.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TestAnonymous {\n    Frame f = new Frame(\"Test Anonymous\");\n    TextField tf = new TextField(30);\n\n    public TestAnonymous() {\n        f.add(new Label(\"Mouse\"), \"North\");\n        f.add(tf, \"South\");\n        f.addMouseMotionListener(\n                new MouseMotionAdapter() {\n                    public void mouseDragged(MouseEvent e) {\n                        String s = \"(\" + e.getX() + \",\" + e.getY() + \")\";\n                        tf.setText(s);\n                    }\n\n                    public void mouseMoved(MouseEvent e) {\n                    }\n                }\n        );\n        f.setSize(300, 200);\n        f.setVisible(true);\n    }\n\n    public static void main(String args[]) {\n        TestAnonymous t = new TestAnonymous();\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestAnonymous2.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TestAnonymous2 {\n    Frame f = new Frame(\"Test\");\n    TextField tf = new TextField(10);\n    Button b1 = new Button(\"Start\");\n\n    public TestAnonymous2() {\n        f.add(b1, \"North\");\n        f.add(tf, \"South\");\n\n        b1.addActionListener(new ActionListener() {\n            private int i;\n\n            public void actionPerformed(ActionEvent e) {\n                tf.setText(e.getActionCommand() + ++i);\n            }\n        });\n\n        f.addWindowListener(new WindowAdapter() {\n            public void windowClosing(WindowEvent e) {\n                System.exit(0);\n            }\n        });\n\n        f.pack();\n        f.setVisible(true);\n    }\n\n    public static void main(String args[]) {\n        new TestAnonymous2();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestBorderLayout.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestBorderLayout {\n    public static void main(String args[]) {\n        Frame f;\n        f = new Frame(\"Border Layout\");\n        Button bn = new Button(\"BN\");\n        Button bs = new Button(\"BS\");\n        Button bw = new Button(\"BW\");\n        Button be = new Button(\"BE\");\n        Button bc = new Button(\"BC\");\n\n        f.add(bn, \"North\");\n        f.add(bs, \"South\");\n        f.add(bw, \"West\");\n        f.add(be, \"East\");\n        f.add(bc, \"Center\");\n\t\t\n\t\t/*\n\t\tf.add(bn, BorderLayout.NORTH);\n\t\tf.add(bs, BorderLayout.SOUTH);\n\t\tf.add(bw, BorderLayout.WEST);\n\t\tf.add(be, BorderLayout.EAST);\n\t\tf.add(bc, BorderLayout.CENTER);\n\t\t*/\n\n        f.setSize(200, 200);\n        f.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestFlowLayout.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestFlowLayout {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"Flow Layout\");\n        Button button1 = new Button(\"Ok\");\n        Button button2 = new Button(\"Open\");\n        Button button3 = new Button(\"Close\");\n        f.setLayout(new FlowLayout(FlowLayout.LEFT));\n        f.add(button1);\n        f.add(button2);\n        f.add(button3);\n        f.setSize(100, 100);\n        f.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestFlowLayout2.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestFlowLayout2 {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"Java Frame\");\n        FlowLayout l = new FlowLayout(FlowLayout.CENTER, 20, 40);\n        f.setLayout(l);\n        f.setLocation(300, 400);\n        f.setSize(300, 200);\n        f.setBackground(new Color(204, 204, 255));\n        for (int i = 1; i <= 7; i++) {\n            f.add(new Button(\"BUTTON\"));\n        }\n        f.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestFrame.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\npublic class TestFrame {\n\tpublic static void main( String args[]) {\n\t\tFrame f = new Frame(\"My First Test\");\n\t\tf.setLocation(300, 300);\n\t\tf.setSize( 170,100);\n\t\tf.setBackground( Color.blue);\n\t\tf.setResizable(false);\n\t\tf.setVisible( true);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestFrameWithPanel.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestFrameWithPanel {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"MyTest Frame\");\n        Panel pan = new Panel();\n        f.setSize(200, 200);\n        f.setBackground(Color.blue);\n        f.setLayout(null);\n        pan.setSize(100, 100);\n        pan.setBackground(Color.green);\n        f.add(pan);\n        f.setVisible(true);\n    }\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestGridLayout.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestGridLayout {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"GridLayout Example\");\n        Button b1 = new Button(\"b1\");\n        Button b2 = new Button(\"b2\");\n        Button b3 = new Button(\"b3\");\n        Button b4 = new Button(\"b4\");\n        Button b5 = new Button(\"b5\");\n        Button b6 = new Button(\"b6\");\n        f.setLayout(new GridLayout(3, 2));\n        f.add(b1);\n        f.add(b2);\n        f.add(b3);\n        f.add(b4);\n        f.add(b5);\n        f.add(b6);\n        f.pack();\n        f.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestInner.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TestInner {\n    Frame f = new Frame(\"Mouse\");\n    TextField tf = new TextField(30);\n\n    public TestInner() {\n        f.add(new Label(\"Mouse\"), \"North\");\n        f.add(tf, \"South\");\n        f.setBackground(new Color(120, 175, 175));\n        f.addMouseMotionListener(new InnerMonitor());\n        f.addMouseListener(new InnerMonitor());\n        f.setSize(300, 200);\n        f.setVisible(true);\n    }\n\n    public static void main(String args[]) {\n        TestInner t = new TestInner();\n    }\n\n    private class InnerMonitor implements MouseMotionListener, MouseListener {\n        public void mouseDragged(MouseEvent e) {\n            String s = \"(\" + e.getX() + \",\" + e.getY() + \")\";\n            tf.setText(s);\n        }\n\n        public void mouseEntered(MouseEvent e) {\n            String s = \"Start\";\n            tf.setText(s);\n        }\n\n        public void mouseExited(MouseEvent e) {\n            String s = \"end\";\n            tf.setText(s);\n        }\n\n        public void mouseMoved(MouseEvent e) {\n        }\n\n        public void mousePressed(MouseEvent e) {\n        }\n\n        public void mouseClicked(MouseEvent e) {\n        }\n\n        public void mouseReleased(MouseEvent e) {\n        }\n    }//end of Inner class\n}//end of Outer class"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestKey.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TestKey {\n    public static void main(String[] args) {\n        new KeyFrame().launchFrame();\n    }\n}\n\nclass KeyFrame extends Frame {\n    public void launchFrame() {\n        setSize(200, 200);\n        setLocation(300, 300);\n        addKeyListener(new MyKeyMonitor());\n        setVisible(true);\n    }\n\n    class MyKeyMonitor extends KeyAdapter {\n        public void keyPressed(KeyEvent e) {\n            int keyCode = e.getKeyCode();\n            if (keyCode == KeyEvent.VK_UP) {\n                System.out.println(\"UP\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestMouseMotion.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.util.*;\n\npublic class TestMouseMotion {\n    public static void main(String args[]) {\n        new MyFrame88(\"drawing...\");\n    }\n}\n\nclass MyFrame88 extends Frame {\n    ArrayList points = null;\n\n    MyFrame88(String s) {\n        super(s);\n        points = new ArrayList();\n        setLayout(null);\n        setBounds(300, 300, 400, 300);\n        this.setBackground(new Color(204, 204, 255));\n        setVisible(true);\n        this.addMouseMotionListener(new Monitor5());\n    }\n\n    public void paint(Graphics g) {\n        Iterator i = points.iterator();\n        while (i.hasNext()) {\n            Point p = (Point) i.next();\n            g.setColor(Color.BLUE);\n            g.fillOval(p.x, p.y, 10, 10);\n        }\n    }\n\n    public void addPoint(Point p) {\n        points.add(p);\n    }\n}\n\nclass Monitor5 extends MouseMotionAdapter {\n    private int num = 0;\n\n    public void mouseMoved(MouseEvent e) {\n        MyFrame88 f = (MyFrame88) e.getSource();\n        f.addPoint(new Point(e.getX(), e.getY()));\n        if (num++ >= 5) {\n            f.repaint();\n            num = 0;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestMouseMotionGeneric.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\nimport java.util.*;\n\npublic class TestMouseMotionGeneric {\n    public static void main(String args[]) {\n        new MyFrame888(\"drawing...\");\n    }\n}\n\nclass MyFrame888 extends Frame {\n    ArrayList<Point> points = null;\n\n    MyFrame888(String s) {\n        super(s);\n        points = new ArrayList<Point>();\n        setLayout(null);\n        setBounds(300, 300, 400, 300);\n        this.setBackground(new Color(204, 204, 255));\n        setVisible(true);\n        this.addMouseMotionListener(new Monitor4());\n    }\n\n    public void paint(Graphics g) {\n        Iterator<Point> i = points.iterator();\n        while (i.hasNext()) {\n            Point p = i.next();\n            g.setColor(Color.BLUE);\n            g.fillOval(p.x, p.y, 10, 10);\n        }\n    }\n\n    public void addPoint(Point p) {\n        points.add(p);\n    }\n}\n\nclass Monitor4 extends MouseMotionAdapter {\n    private int num = 0;\n\n    public void mouseMoved(MouseEvent e) {\n        MyFrame888 f = (MyFrame888) e.getSource();\n        f.addPoint(new Point(e.getX(), e.getY()));\n        if (num++ >= 5) {\n            f.repaint();\n            num = 0;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestMultiFrame.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestMultiFrame {\n    public static void main(String args[]) {\n        MyFrame4 f1 =\n                new MyFrame4(100, 100, 200, 200, Color.BLUE);\n        MyFrame4 f2 =\n                new MyFrame4(300, 100, 200, 200, Color.YELLOW);\n        MyFrame4 f3 =\n                new MyFrame4(100, 300, 200, 200, Color.GREEN);\n        MyFrame4 f4 =\n                new MyFrame4(300, 300, 200, 200, Color.MAGENTA);\n    }\n}\n\n\nclass MyFrame4 extends Frame {\n    static int id = 0;\n\n    MyFrame4(int x, int y, int w, int h, Color color) {\n        super(\"MyFrame4 \" + (++id));\n        setBackground(color);\n        setLayout(null);\n        setBounds(x, y, w, h);\n        setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestMultiPanel.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestMultiPanel {\n    public static void main(String args[]) {\n        new MyFrame2(\"MyFrameWithPanel\", 300, 300, 400, 300);\n    }\n}\n\n\nclass MyFrame2 extends Frame {\n    private Panel p1, p2, p3, p4;\n\n    MyFrame2(String s, int x, int y, int w, int h) {\n        super(s);\n        setLayout(null);\n        p1 = new Panel(null);\n        p2 = new Panel(null);\n        p3 = new Panel(null);\n        p4 = new Panel(null);\n        p1.setBounds(0, 0, w / 2, h / 2);\n        p2.setBounds(0, h / 2, w / 2, h / 2);\n        p3.setBounds(w / 2, 0, w / 2, h / 2);\n        p4.setBounds(w / 2, h / 2, w / 2, h / 2);\n        p1.setBackground(Color.BLUE);\n        p2.setBackground(Color.GREEN);\n        p3.setBackground(Color.YELLOW);\n        p4.setBackground(Color.MAGENTA);\n        add(p1);\n        add(p2);\n        add(p3);\n        add(p4);\n        setBounds(x, y, w, h);\n        setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestPaint.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestPaint {\n    public static void main(String[] args) {\n        new PaintFrame().launchFrame();\n    }\n}\n\nclass PaintFrame extends Frame {\n\n    public void launchFrame() {\n        setBounds(200, 200, 640, 480);\n        setVisible(true);\n    }\n\n    public void paint(Graphics g) {\n        Color c = g.getColor();\n        g.setColor(Color.red);\n        g.fillOval(50, 50, 30, 30);\n        g.setColor(Color.green);\n        g.fillRect(80, 80, 40, 40);\n        g.setColor(c);\n    }\n\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestPanel.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\n\npublic class TestPanel {\n    public static void main(String args[]) {\n        Frame f = new Frame(\"Java Frame with Panel\");\n        Panel p = new Panel(null);\n        f.setLayout(null);\n        f.setBounds(300, 300, 500, 500);\n        f.setBackground(new Color(0, 0, 102));\n        p.setBounds(50, 50, 400, 400);\n        p.setBackground(new Color(204, 204, 255));\n        f.add(p);\n        f.setVisible(true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1000/TestWindowClose.java",
    "content": "package com.basic.chapter1000;\n\nimport java.awt.*;\nimport java.awt.event.*;\n\npublic class TestWindowClose {\n    public static void main(String args[]) {\n        new MyFrame55(\"MyFrame\");\n    }\n}\n\nclass MyFrame55 extends Frame {\n    MyFrame55(String s) {\n        super(s);\n        setLayout(null);\n        setBounds(300, 300, 400, 300);\n        this.setBackground(new Color(204, 204, 255));\n        setVisible(true);\n        //this.addWindowListener(new MyWindowMonitor());\n\n        this.addWindowListener(\n                new WindowAdapter() {\n                    public void windowClosing(WindowEvent e) {\n                        setVisible(false);\n                        System.exit(-1);\n                    }\n                });\n\n    }\n  /*\n  class MyWindowMonitor extends WindowAdapter {\n  \tpublic void windowClosing(WindowEvent e) {\n  \t\tsetVisible(false);\n  \t\tSystem.exit(0);\n  \t}\n  }\n  */\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1100/TestReflect.java",
    "content": "package com.basic.chapter1100;\n\nimport java.lang.reflect.*;\n\n/**\n * 反射\n *\n * @author MarkShen\n * @since 20191130\n */\npublic class TestReflect {\n\tpublic static void main(String[] args) throws Exception {\n\t\t//m1();\n\t\t//m2();\n\t\t//m3(\"java.lang.Thread\");\n\t\t//m4();\n\t\t//m5();\n\t\t//m6();\n\t\t//String s = \"java.lang.String\"; //从文件里读出来的\n\t\t//new s()\n\t\t//m7();\n\t\t//m8();\n\t\t//m9();\n\t\tm10();\n\t}\n\n\tprivate static void m1() {\n\t\tString s = new String();\n\t\tClass c = s.getClass();\n\t\tSystem.out.println(c);\n\t\tClass su = c.getSuperclass();\n\t\tSystem.out.println(su);\n\t\tSystem.out.println(su.getSuperclass());\n\t}\n\n\tprivate static void m2() {\n\t\tClass c = String.class;\n\t\tSystem.out.println(c);\n\t}\n\n\tprivate static void m3(String className) {\n\t\ttry {\n\t\t\tClass.forName(className);\n\t\t} catch (ClassNotFoundException e) {\n\t\t\tSystem.out.println(\"this class doesn't exist!\");\n\t\t}\n\t}\n\n\tprivate static void m4() {\n\t\tint m = String.class.getModifiers();\n\t\tSystem.out.println(Modifier.isPublic(m));\n\t\tSystem.out.println(Modifier.isFinal(m));\n\t\tSystem.out.println(Modifier.isStatic(m));\n\t}\n\n\tprivate static void m5() {\n\t\tfor(Class c : String.class.getInterfaces()) {\n\t\t\tSystem.out.println(c);\n\t\t}\n\t\tSystem.out.println(java.lang.Comparable.class.isInterface());\n\t}\n\n\tprivate static void m6() {\n\t\tField[] fs = System.class.getFields();\n\t\tfor(Field f : fs) {\n\t\t\tSystem.out.println(f);\n\t\t}\n\t}\n\n\tprivate static void m7() throws Exception {\n\t\tConstructor[] cs = String.class.getConstructors();\n\t\tfor(Constructor c : cs) {\n\t\t\tSystem.out.println(c);\n\t\t\tfor(Class paraClass : c.getParameterTypes()) {\n\t\t\t\tSystem.out.print(paraClass + \" \");\n\t\t\t}\n\t\t\tSystem.out.println();\n\t\t}\n\n\t\tString.class.newInstance();\n\t}\n\n\tprivate static void m8() throws Exception {\n\t\tClass[] argClasses = new Class[] {int.class, int.class};\n\t\tObject[] args = new Object[] {new Integer(12), new Integer(24)};\n\t\tConstructor c = java.awt.Point.class.getConstructor(argClasses);\n\t\tObject o = c.newInstance(args);\n\t\tSystem.out.println(o);\n\t}\n\n\tprivate static void m9() throws Exception {\n\t\tClass[] argClasses = new Class[] {String.class};\n\t\tObject[] args = new Object[] {new String(\"world!\")};\n\t\tMethod m = java.lang.String.class.getMethod(\"concat\", argClasses);\n\t\tString result = (String)m.invoke(new String(\"hello\"), args);\n\t\tSystem.out.println(result);\n\t}\n\n\tprivate static void m10() throws Exception {\n\t\t/*\n\t\tClass cls = Class.forName(\"java.lang.String\");\n\t\tObject arr = Array.newInstance(cls, 10);\n\t\tArray.set(arr, 5, \"this is a test\");\n\t\tString s = (String)Array.get(arr, 5);\n\t\tSystem.out.println(s);\n\t\t*/\n\n\t\t//例中创建了一个 5 x 10 x 15 的整型数组，并为处于 [3][5][10] 的元素赋了值为 37。\n\t\t//注意，多维数组实际上就是数组的数组，例如，第一个 Array.get 之后，\n\t\t//arrobj 是一个 10 x 15 的数组。进而取得其中的一个元素，即长度为 15 的数组，\n\t\t//并使用 Array.setInt 为它的第 10 个元素赋值。\n\n\t\tint dims[] = new int[]{5, 10, 15};\n\t\tObject arr = Array.newInstance(Integer.TYPE, dims);\n\t\tObject arrobj = Array.get(arr, 3);\n\t\tClass cls = arrobj.getClass().getComponentType();\n\t\tSystem.out.println(cls);\n\t\tarrobj = Array.get(arrobj, 5);\n\t\tArray.setInt(arrobj, 10, 37);\n\t\tint arrcast[][][] = (int[][][]) arr;\n\t\tSystem.out.println(arrcast[3][5][10]);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/basic/chapter1200/QQClient.java",
    "content": "package com.basic.chapter1200;\n\npublic class QQClient {\n}\n"
  },
  {
    "path": "src/main/java/com/basic/chapter1200/QQServer.java",
    "content": "package com.basic.chapter1200;\n\npublic class QQServer {\n}\n"
  },
  {
    "path": "src/main/java/com/geo/GeoTest.java",
    "content": "package com.geo;\n\nimport com.maxmind.geoip2.DatabaseReader;\nimport com.maxmind.geoip2.model.CityResponse;\nimport com.maxmind.geoip2.record.*;\n\nimport java.io.File;\nimport java.net.InetAddress;\n\n/**\n * 根据ip地址获取ip地址所在地\n * https://github.com/maxmind/GeoIP2-java\n *\n * @author MarkShen\n * @since 20191204\n */\npublic class GeoTest {\n    static String IP = \"182.61.200.6\";\n\n    /**\n     * 指定数据库路径\n     */\n    static String DATABASE_PATH = System.getProperty(\"user.dir\") + \"/src/main/java/com/geo/GeoLite2-City.mmdb\";\n\n    public static void main(String[] args) throws Exception {\n        // A File object pointing to your GeoIP2 or GeoLite2 database\n        File database = new File(DATABASE_PATH);\n\n        // This creates the DatabaseReader object. To improve performance, reuse\n        // the object across lookups. The object is thread-safe.\n        DatabaseReader reader = new DatabaseReader.Builder(database).build();\n\n        InetAddress ipAddress = InetAddress.getByName(IP);\n\n        // Replace \"city\" with the appropriate method for your database, e.g.,\n        // \"country\".\n        CityResponse response = reader.city(ipAddress);\n\n        Country country = response.getCountry();\n        System.out.println(country.getIsoCode());            // 'US'\n        System.out.println(country.getName());               // 'United States'\n        System.out.println(country.getNames().get(\"zh-CN\")); // '美国'\n\n        Subdivision subdivision = response.getMostSpecificSubdivision();\n        System.out.println(subdivision.getName());    // 'Minnesota'\n        System.out.println(subdivision.getIsoCode()); // 'MN'\n\n        City city = response.getCity();\n        System.out.println(city.getName()); // 'Minneapolis'\n\n        Postal postal = response.getPostal();\n        System.out.println(postal.getCode()); // '55455'\n\n        Location location = response.getLocation();\n        System.out.println(location.getLatitude());  // 44.9733\n        System.out.println(location.getLongitude()); // -93.2323\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java10/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java10;\n\n/**\n * @author MarkShen\n * @see https://www.oracle.com/technetwork/java/javase/10-relnote-issues-4108729.html\n * @see https://openjdk.org/projects/jdk/10/\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 10 Features and Enhancements\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java11/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java11;\n\n/**\n * @author MarkShen\n * @see https://www.oracle.com/technetwork/java/javase/11-relnotes-5012447.html\n * @see https://openjdk.org/projects/jdk/11/\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 11 Features and Enhancements\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java12/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java12;\n\n/**\n * @author MarkShen\n * @see https://www.oracle.com/technetwork/java/javase/12-relnote-issues-5211422.html\n * @see https://openjdk.org/projects/jdk/12/\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 12 Features and Enhancements\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java13/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java13;\n\n/**\n * @author MarkShen\n * @see https://www.oracle.com/technetwork/java/13-relnote-issues-5460548.html\n * @see https://openjdk.org/projects/jdk/13/\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 13 Features and Enhancements\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java14/Java14NewFeatures.java",
    "content": "package com.java14;\n\n/**\n * @author MarkShen1992\n * @see https://www.oracle.com/technetwork/java/javase/14all-relnotes-5809668.html\n * @see https://www.codejava.net/java-se/java-14-new-features\n * @see https://openjdk.org/projects/jdk/14/\n */\npublic class Java14NewFeatures {\n    public static void main(String[] args) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java15/NewFeatures.java",
    "content": "package com.java15;\n\n/**\n * jdk15 new feature\n *\n * https://openjdk.java.net/projects/jdk/15/\n * https://javaalmanac.io/jdk/15/\n * https://www.youtube.com/watch?v=uTNjeM0G9Nk\n * https://openjdk.org/projects/jdk/15/\n */\npublic class NewFeatures {\n    public static void main(String[] args) {\n        System.out.println(\"jdk 15 new features.\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java16/Java16NewFeatures.java",
    "content": "package com.java16;\n\n/**\n * // Java 16 new features\n * // 1) https://openjdk.java.net/projects/jdk/16/\n * // 2) https://mkyong.com/java/what-is-new-in-java-16/\n * @author MarkShen\n */\npublic class Java16NewFeatures {\n    public static void main(String[] args) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java17/Java17NewFeatures.java",
    "content": "package com.java17;\n\n/**\n * https://www.baeldung.com/java-17-new-features https://mkyong.com/java/what-is-new-in-java-17/\n * https://www.geeksforgeeks.org/jdk-17-new-features-in-java-17/\n * @see https://openjdk.org/projects/jdk/17/\n *\n * @author MarkShen\n */\npublic class Java17NewFeatures {\n    public static void main(String[] args) {\n        System.out.println(\"Java 17 new Features.\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java18/Java18Features.java",
    "content": "package com.java18;\n\n/**\n * Java 18 features\n * https://openjdk.org/projects/jdk/18/\n * https://www.developer.com/java/java-18-features/\n */\npublic class Java18Features {\n    public static void main(String[] args) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java19/Java19Features.java",
    "content": "package com.java19;\n\n/**\n * Java 19 features\n * https://openjdk.org/projects/jdk/19/\n * https://www.infoworld.com/article/3653331/jdk-19-the-new-features-in-java-19.html\n */\npublic class Java19Features {\n    public static void main(String[] args) {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java5/NewFeatures.java",
    "content": "/**\n * \n */\npackage com.java5;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.List;\n\n/**\n * @author MarkShen\n *\n */\npublic class NewFeatures {\n  public static void print(int ...is) {\n    for (int num : is) {\n      System.out.println(num);\n    }\n  }\n  \n  public static void main(String[] args) {\n    // Enhanced For loop\n    List numbers = new ArrayList();\n    numbers.add(1);\n    numbers.add(2);\n    numbers.add(3);\n\n    Iterator numbersIterator = null;\n    for (numbersIterator = numbers.iterator(); numbersIterator.hasNext();) {\n      System.out.println(numbersIterator.next());;\n    }\n    \n    for (Object o : numbers) {\n      System.out.println(o);\n    }\n    \n    // VariableArguments\n    print(new int[] {1,2,4});\n    \n    // Static Imports\n    \n    \n    // Enumerations(Typesafe Enums)\n    \n    // 自动装箱与自动拆箱(Autoboxing/Unboxing)\n    \n    // 引入泛型(Generics)\n    \n    // 元数据（注解） (Metadata Annotations)\n    \n    // 引入Instrumentation\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java6/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java6;\n\n/**\n * @author MarkShen\n * @see https://www.oracle.com/technetwork/java/javase/features-141434.html\n * @see https://www.oracle.com/technical-resources/articles/javase/beta2.html\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 6 Features and Enhancements\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java7/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java7;\n\n/**\n * @author MarkShen\n * https://openjdk.org/projects/jdk7/features/\n * @see https://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 7 Features and Enhancements\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Demo0100_LambdaRunnable.java",
    "content": "package com.java8;\n\n/**\n * @author MarkShen\n */\npublic class Demo0100_LambdaRunnable {\n    public static void main(String[] args) {\n        // 用lambda表达式实现Runnable\n        // Java 8之前：\n        new Thread(new Runnable() {\n            @Override\n            public void run() {\n                System.out.println(\"Before Java8, too much code for too little to do\");\n            }\n        }).start();\n\n        //Java 8方式：\n        new Thread( () -> System.out.println(\"In Java8, Lambda expression rocks !!\") ).start();\n\n        // 这个例子向我们展示了Java 8 lambda表达式的语法。你可以使用lambda写出如下代码\n        // (params) -> expression\n        // (params) -> statement\n        // (params) -> { statements }\n\n        // 如果你的方法不对参数进行修改、重写，只是在控制台打印点东西的话\n        // () -> System.out.println(\"Hello Lambda Expressions\");\n\n        // 如果你的方法接收两个参数\n        // (int even, int odd) -> even + odd\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Demo0200_LambdaIterator.java",
    "content": "package com.java8;\n\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * @author MarkShen\n */\npublic class Demo0200_LambdaIterator {\n    public static void main(String[] args) {\n        // Java 8之前：\n        List<String> features = Arrays.asList(\"Lambdas\", \"Default Method\", \"Stream API\", \"Date and Time API\");\n        for (String feature : features) {\n            System.out.println(feature);\n        }\n\n        System.out.println(\"---------------------------------\");\n        // Java 8之后：\n        features.forEach(n -> System.out.println(n));\n\n        // 使用Java 8的方法引用更方便，方法引用由::双冒号操作符标示，\n        // 看起来像C++的作用域解析运算符\n        System.out.println(\"---------------------------------\");\n        features.forEach(System.out::println);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Demo0300_LambdaPredicate.java",
    "content": "package com.java8;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.function.Predicate;\n\n/**\n * @author MarkShen\n */\npublic class Demo0300_LambdaPredicate {\n    public static void main(String[] args) {\n        List<String> languages = Arrays.asList(\"Java\", \"Scala\", \"C++\", \"Haskell\", \"Lisp\");\n\n        System.out.println(\"Languages which starts with J :\");\n        // filter(languages, (str)->str.startsWith(\"J\"));\n\n        System.out.println(\"Languages which ends with a \");\n        // filter(languages, (str)->str.endsWith(\"a\"));\n\n        System.out.println(\"Print all languages :\");\n        filter(languages, (str)->true);\n\n        System.out.println(\"Print no language : \");\n        filter(languages, (str)->false);\n\n        System.out.println(\"Print language whose length greater than 4:\");\n        // filter(languages, (str)->str.length() > 4);\n\n        // 甚至可以用and()、or()和xor()逻辑函数来合并Predicate，\n        // 例如要找到所有以J开始，长度为四个字母的名字，你可以合并两个Predicate并传入\n        Predicate<String> startsWithJ = (n) -> n.startsWith(\"J\");\n        Predicate<String> fourLetterLong = (n) -> n.length() == 4;\n        languages.stream()\n                .filter(startsWithJ.and(fourLetterLong))\n                .forEach((n) -> System.out.print(\"nName, which starts with 'J' and four letter long is : \" + n));\n    }\n\n    /**\n     * filter\n     *\n     * @param names\n     * @param condition\n     */\n    public static void filter(List<String> names, Predicate condition) {\n        for (String name : names) {\n            if (condition.test(name)) {\n                System.out.println(name + \" \");\n            }\n        }\n    }\n\n    // 更好的办法\n    public static void betterFilter(List names, Predicate condition) {\n        names.stream().filter((name) -> (condition.test(name))).forEach((name) -> {\n            System.out.println(name + \" \");\n        });\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Demo0400_LambdaMapReduce.java",
    "content": "package com.java8;\n\nimport java.util.Arrays;\nimport java.util.IntSummaryStatistics;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n/**\n * @author MarkShen\n */\npublic class Demo0400_LambdaMapReduce {\n    public static void main(String[] args) {\n        // 不使用lambda表达式为每个订单加上12%的税\n        List<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);\n        for (Integer cost : costBeforeTax) {\n            double price = cost + .12*cost;\n            System.out.println(price);\n        }\n\n        // 使用lambda表达式\n        costBeforeTax.stream().map((cost) -> cost + .12*cost).forEach(System.out::println);\n\n\n\n        // 为每个订单加上12%的税\n        // 老方法：\n        double total = 0;\n        for (Integer cost : costBeforeTax) {\n            double price = cost + .12*cost;\n            total = total + price;\n        }\n        System.out.println(\"Total : \" + total);\n\n        // 新方法：\n        double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum + cost).get();\n        System.out.println(\"Total : \" + bill);\n\n\n        // 创建一个字符串列表，每个字符串长度大于2\n        List<String> strList = Arrays.asList(\"Java\", \"Scala\", \"C++\", \"Haskell\", \"Lisp\");\n        List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());\n        System.out.printf(\"Original List : %s, filtered list : %s %n\", strList, filtered);\n\n\n        // 将字符串换成大写并用逗号链接起来\n        List<String> G7 = Arrays.asList(\"USA\", \"Japan\", \"France\", \"Germany\", \"Italy\", \"U.K.\",\"Canada\");\n        String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(\", \"));\n        System.out.println(G7Countries);\n\n        // 用所有不同的数字创建一个正方形列表\n        List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);\n        List<Integer> distinct = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());\n        System.out.printf(\"Original List : %s,  Square Without duplicates : %s %n\", numbers, distinct);\n\n        //获取数字的个数、最小值、最大值、总和以及平均值\n        List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);\n        IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();\n        System.out.println(\"Highest prime number in List : \" + stats.getMax());\n        System.out.println(\"Lowest prime number in List : \" + stats.getMin());\n        System.out.println(\"Sum of all prime numbers : \" + stats.getSum());\n        System.out.println(\"Average of all prime numbers : \" + stats.getAverage());\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Demo0500_LambdaSimpleDemo.java",
    "content": "package com.java8;\n\n/**\n * @author MarkShen\n */\npublic class Demo0500_LambdaSimpleDemo {\n    public static void main(String[] args) {\n        // 1. 不需要参数,返回值为 5\n        // () -> 5\n\n        // 2. 接收一个参数(数字类型),返回其2倍的值\n        // x -> 2 * x\n\n        // 3. 接受2个参数(数字),并返回他们的差值\n        // (x, y) -> x – y\n\n        // 4. 接收2个int型整数,返回他们的和\n        // (int x, int y) -> x + y\n\n        // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)\n        // (String s) -> System.out.print(s)\n\n        Demo0500_LambdaSimpleDemo tester = new Demo0500_LambdaSimpleDemo();\n\n        // 类型声明\n        MathOperation addition = (int a, int b) -> a + b;\n\n        // 不用类型声明\n        MathOperation subtraction = (a, b) -> a - b;\n\n        // 大括号中的返回语句\n        MathOperation multiplication = (int a, int b) -> {\n            return a * b;\n        };\n\n        // 没有大括号及返回语句\n        MathOperation division = (int a, int b) -> a / b;\n\n        System.out.println(\"10 + 5 = \" + tester.operate(10, 5, addition));\n        System.out.println(\"10 - 5 = \" + tester.operate(10, 5, subtraction));\n        System.out.println(\"10 x 5 = \" + tester.operate(10, 5, multiplication));\n        System.out.println(\"10 / 5 = \" + tester.operate(10, 5, division));\n\n        // 不用括号\n        GreetingService greetService1 = message -> System.out.println(\"Hello \" + message);\n\n        // 用括号\n        GreetingService greetService2 = (message) -> System.out.println(\"Hello \" + message);\n\n        greetService1.sayMessage(\"Runoob\");\n        greetService2.sayMessage(\"Google\");\n    }\n\n    interface MathOperation {\n        int operation(int a, int b);\n    }\n\n    interface GreetingService {\n        void sayMessage(String message);\n    }\n\n    private int operate(int a, int b, MathOperation mathOperation) {\n        return mathOperation.operation(a, b);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Demo0600_Stream.java",
    "content": "package com.java8;\n\nimport java.util.Arrays;\nimport java.util.IntSummaryStatistics;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.stream.Collectors;\n\n/**\n * Stream 01\n * @author MarkShen\n */\npublic class Demo0600_Stream {\n    public static void main(String[] args) {\n        /**\n        +--------------------+       +------+   +------+   +---+   +-------+\n        | stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|\n        +--------------------+       +------+   +------+   +---+   +-------+\n         */\n        List<String> strings = Arrays.asList(\"abc\", \"\", \"bc\", \"efg\", \"abcd\",\"\", \"jkl\");\n        List<String> filtered = strings.stream().filter(e -> !e.isEmpty()).collect(Collectors.toList());\n        filtered.forEach(System.out::println);\n\n        System.out.println();\n\n        Random random = new Random();\n        random.ints().limit(10).forEach(System.out::println);\n\n        System.out.println();\n\n        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);\n        List<Integer> squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());\n        squaresList.forEach(System.out::println);\n\n        List<String> strs = Arrays.asList(\"abc\", \"\", \"bc\", \"efg\", \"abcd\",\"\", \"jkl\");\n        long count = strs.stream().filter(s -> s.isEmpty()).count();\n        System.out.println(count);\n\n        System.out.println();\n\n        Random rdm = new Random();\n        rdm.ints().limit(10).sorted().forEach(System.out::println);\n\n        System.out.println();\n\n        List<String> parallelStrings = Arrays.asList(\"abc\", \"\", \"bc\", \"efg\", \"abcd\",\"\", \"jkl\");\n        // 获取空字符串的数量\n        long countNum = parallelStrings.parallelStream().filter(s -> s.isEmpty()).count();\n        System.out.println(countNum);\n\n        System.out.println();\n\n        List<String> ss = Arrays.asList(\"abc\", \"\", \"bc\", \"efg\", \"abcd\",\"\", \"jkl\");\n        List<String> filteredList = ss.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());\n        System.out.println(\"筛选列表: \" + filteredList);\n        String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(\", \"));\n        System.out.println(\"合并字符串: \" + mergedString);\n\n        System.out.println();\n\n        List<Integer> numberList = Arrays.asList(3, 2, 2, 3, 7, 3, 5);\n        IntSummaryStatistics stats = numberList.stream().mapToInt((x) -> x).summaryStatistics();\n        System.out.println(\"列表中最大的数 : \" + stats.getMax());\n        System.out.println(\"列表中最小的数 : \" + stats.getMin());\n        System.out.println(\"所有数之和 : \" + stats.getSum());\n        System.out.println(\"平均数 : \" + stats.getAverage());\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Demo0700_Stream.java",
    "content": "package com.java8;\n\nimport java.util.*;\nimport java.util.function.Supplier;\nimport java.util.stream.Collectors;\nimport java.util.stream.IntStream;\nimport java.util.stream.Stream;\n\n/**\n * Stream 02\n * @author MarkShen\n * https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html\n */\npublic class Demo0700_Stream {\n    public static void main(String[] args) {\n        /**\n         * how to build stream\n         */\n        // 1. Individual values\n        Stream stream = Stream.of(\"a\", \"b\", \"c\");\n\n        // 2. Arrays\n        String [] strArray = new String[] {\"a\", \"b\", \"c\"};\n        stream = Stream.of(strArray);\n        stream = Arrays.stream(strArray);\n\n        // 3. Collections\n        List<String> list = Arrays.asList(strArray);\n        stream = list.stream();\n\n        /**\n         * number stream build\n         */\n        IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println);\n        IntStream.range(1, 3).forEach(System.out::println);\n        IntStream.rangeClosed(1, 3).forEach(System.out::println);\n\n        /**\n         * other data structure from stream\n         */\n        String[] strArr = {\"a\", \"b\", \"c\"};\n        // 1. Array, List, Set, Stack, String\n        String[] sArr = Arrays.stream(strArr).toArray(String[]::new);\n        List<String> list1 = Arrays.stream(strArr).collect(Collectors.toList());\n        List<String> list2 = Arrays.stream(strArr).collect(Collectors.toCollection(ArrayList::new));\n        Set<String> set1 = Arrays.stream(strArr).collect(Collectors.toSet());\n        Stack<String> stack1 = Arrays.stream(strArr).collect(Collectors.toCollection(Stack::new));\n        String str = Arrays.stream(strArr).collect(Collectors.joining(\", \"));\n\n        // convert all elements to upper case\n        List<String> myList = Arrays.asList(\"a1\", \"a2\", \"b1\", \"c2\", \"c1\");\n        myList.stream()\n                .filter(e -> e.startsWith(\"c\"))\n                .map(String::toUpperCase)\n                .sorted()\n                .forEach(System.out::println);\n\n        Stream<List<Integer>> inputStream = Stream.of(\n                Arrays.asList(1),\n                Arrays.asList(2, 3),\n                Arrays.asList(4, 5, 6)\n        );\n        Stream<Integer> outputStream = inputStream.\n                flatMap((childList) -> childList.stream());\n        outputStream.forEach(System.out::println);\n\n        System.out.println();\n\n        Stream.of(\"one\", \"two\", \"three\", \"four\")\n                .filter(e -> e.length() > 3)\n                .peek(e -> System.out.println(\"Filtered value: \" + e))\n                .map(String::toUpperCase)\n                .peek(e -> System.out.println(\"Mapped value: \" + e))\n                .collect(Collectors.toList());\n\n        System.out.println();\n\n        Stream.of(\"one\", \"two\", \"three\", \"four\")\n                .findFirst().ifPresent(System.out::println);\n\n        System.out.println();\n\n        // 字符串连接，concat = \"ABCD\"\n        String concat = Stream.of(\"A\", \"B\", \"C\", \"D\").reduce(\"\", String::concat);\n        // 求最小值，minValue = -3.0\n        double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);\n        // 求和，sumValue = 10, 有起始值\n        int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);\n        // 求和，sumValue = 10, 无起始值\n        sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();\n        // 过滤，字符串连接，concat = \"ace\"\n        concat = Stream.of(\"a\", \"B\", \"c\", \"D\", \"e\", \"F\").\n                filter(x -> x.compareTo(\"Z\") > 0).\n                reduce(\"\", String::concat);\n\n        System.out.println();\n\n        Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)\n                .limit(3)\n                .skip(2)\n                .collect(Collectors.toList()).forEach(System.out::println);\n\n        System.out.println();\n\n        List<Person> people = new ArrayList<>();\n        for (int i = 0; i < 10; i ++) {\n            people.add(new Person(i, \"name\" + i));\n        }\n        people.add(new Person(10, \"name0\"));\n\n        // 根据 name 属性降序输出\n        people.stream()\n                .sorted(Comparator.comparing(Person::getName).reversed())\n                .collect(Collectors.toList())\n                .forEach(System.out::println);\n\n        Map<String, List<Person>> result = people.stream()\n                .collect(Collectors.groupingBy(Person::getName));\n        System.out.println(result);\n\n        long c = people.stream().filter(x -> x.getId() > 5).count();\n        System.out.println(c);\n\n        long resultNum = people.stream().map(Person::getName).distinct().count();\n        System.out.println(resultNum);\n\n        Optional<Person> min = people.stream().min(Comparator.comparing(Person::getId));\n        System.out.println(min.get());\n\n        Optional<Person> max = people.stream().max(Comparator.comparing(Person::getId));\n        max.ifPresent(System.out::println);\n\n        Random seed = new Random();\n        Supplier<Integer> random = seed::nextInt;\n        Stream.generate(random).limit(10).forEach(System.out::println);\n        // Another way\n        IntStream.generate(() -> (int) (System.nanoTime() % 100)).\n                limit(10).forEach(System.out::println);\n\n        Stream.iterate(0, n -> n + 3).limit(10). forEach(x -> System.out.print(x + \" \"));\n\n        Map<Boolean, List<Person>> resultMap = people.stream()\n                .collect(Collectors.partitioningBy(p -> p.getId() < 6));\n        System.out.println(resultMap);\n    }\n}"
  },
  {
    "path": "src/main/java/com/java8/Demo0800_Stream.java",
    "content": "package com.java8;\n\nimport java.util.*;\nimport java.util.stream.Collectors;\n\npublic class Demo0800_Stream {\n    public static void main(String[] args) {\n        List<Person> persons = Arrays.asList(new Person(1, \"Bob\", 21, 1), new Person(2, \"Alice\", 25, 0),\n            new Person(4, \"Calvin\", 26, 1), new Person(3, \"Susan\", 34, 0), new Person(5, \"Trump\", 70, 1));\n\n        Person persion = persons.stream().filter(p -> p.getName().equals(\"Bob\")).findFirst().orElse(null);\n        System.out.println(persion);\n\n        // 人小于等于25的人的名字\n        List<String> names =\n            persons.stream().filter(p -> p.getAge() <= 25).map(Person::getName).collect(Collectors.toList());\n\n        System.out.println(names);\n\n        // 分页查询实现\n        int pageIndex = 1;\n        int pageSize = 2;\n        int recordIndex = (pageIndex - 1) * pageSize;\n        List<Person> pagedPerson = persons.stream().skip(recordIndex) // 每页第一条数据的位置\n            .limit(pageSize) // 页面大小\n            .collect(Collectors.toList());\n\n        System.out.println(pagedPerson);\n\n        // Searching\n        Optional<Person> any = persons.stream().filter(p -> p.getAge() < 25).findAny();\n\n        System.out.println(any);\n        System.out.println(persons.stream().anyMatch(p -> p.getAge() < 25));\n\n        // Reordering Descending\n        List<Person> sortedPersons = persons.stream().sorted(Comparator.comparing(Person::getAge).reversed()) // 升序\n            .collect(Collectors.toList());\n\n        System.out.println(sortedPersons);\n\n        // Summarizing\n        int sum = 0;\n        sum = persons.stream().mapToInt(Person::getAge).reduce(0, (total, currentVal) -> total + currentVal);\n        System.out.println(sum);\n\n        sum = persons.stream().mapToInt(Person::getAge).sum();\n        System.out.println(sum);\n\n        long count = 0;\n        count = persons.stream().mapToInt(Person::getAge).count();\n        System.out.println(count);\n\n        // calculating summary\n        IntSummaryStatistics ageStatistics = persons.stream().mapToInt(Person::getAge).summaryStatistics();\n        System.out.println(ageStatistics.getAverage());\n        System.out.println(ageStatistics.getCount());\n        System.out.println(ageStatistics.getMax());\n        System.out.println(ageStatistics.getMin());\n        System.out.println(ageStatistics.getSum());\n\n        // Grouping\n        Map<Integer, List<Person>> peopleGroupBySex =\n            persons.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.toList()));\n        System.out.println(peopleGroupBySex);\n\n        Map<Integer, List<String>> nameByGender = persons.stream()\n            .collect(Collectors.groupingBy(Person::getSex, Collectors.mapping(Person::getName, Collectors.toList())));\n        System.out.println(nameByGender);\n\n        Map<Integer, Double> averageAgeByGender =\n            persons.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.averagingInt(Person::getAge)));\n        System.out.println(averageAgeByGender);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java8;\n\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * @author MarkShen\n * @see https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html\n * @see https://openjdk.org/projects/jdk8/features\n * @see http://www.importnew.com/16436.html\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 8 Features and Enhancements\n    List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});\n    int factor = 2;\n    primes.forEach(element -> { System.out.println(factor*element); });\n    primes.forEach(element -> System.out.println(factor*element));\n    primes.forEach(e -> System.out.println(\"Hello World \" + e));\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/java8/Person.java",
    "content": "package com.java8;\n\npublic class Person {\n    private int id;\n    private String name;\n    private int age;\n    private int sex;\n\n    public Person() {}\n\n    public Person(int id, String name) {\n        this.id = id;\n        this.name = name;\n    }\n\n    public Person(int id, String name, int age, int sex) {\n        this.id = id;\n        this.name = name;\n        this.age = age;\n        this.sex = sex;\n    }\n\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        this.age = age;\n    }\n\n    public int getSex() {\n        return sex;\n    }\n\n    public void setSex(int sex) {\n        this.sex = sex;\n    }\n\n    @Override\n    public String toString() {\n        return \"Person{\" +\n            \"id=\" + id +\n            \", name='\" + name + '\\'' +\n            \", age='\" + age + '\\'' +\n            \", sex=\" + sex +\n            '}';\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/java9/NewFeatures.java",
    "content": "/**\n *\n */\npackage com.java9;\n\n/**\n * @author MarkShen\n * @see https://docs.oracle.com/javase/9/whatsnew/toc.htm#JSNEW-GUID-C23AFD78-C777-460B-8ACE-58BE5EA681F6\n * @see https://openjdk.org/projects/jdk9/\n */\npublic class NewFeatures {\n  public static void main(String[] args) {\n    // Java SE 9 Features and Enhancements\n  }\n}\n"
  },
  {
    "path": "src/main/java/com/jvm/OutOfMemoryException.java",
    "content": "package com.jvm;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author MarkShen\n * @since 20190622\n * Exception: OutOfMemoryError 抛出，可以改造成多线程往List里面加\n */\npublic class OutOfMemoryException {\n    static List<Object> os = new ArrayList<>();\n\n    public static void main(String[] args) {\n        while (true) {\n            os.add(new Object());\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent01/T.java",
    "content": "package com.mark.concurrent01;\n\n/**\n * synchronized关键字\n * 对对象加锁\n * @author MarkShen\n */\npublic class T {\n\n\tprivate int count = 10;\n\tprivate static Object o = new Object();  // 有 static 和没有 static 有什么区别吗?\n\t\n\tpublic void m() {\n\t\tsynchronized(o) { // 任何线程要执行下面的代码， 必须先拿到o的锁(互斥锁)\n\t\t\tcount --;\n\t\t\tSystem.out.println(Thread.currentThread().getName() + \"\" + count);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent02/T.java",
    "content": "package com.mark.concurrent02;\n\n/**\n * synchronized关键字\n * 对当前对象加锁\n * @author MarkShen\n */\npublic class T {\n\n\tprivate int count = 10;\n\n\tpublic void m() {\n\t\t// lock current object.\n\t\tsynchronized(this) { // 任何线程要执行下面的代码， 必须先拿到this的锁, 锁定this对象, 锁对象， 而不是代码块\n\t\t\tcount --;\n\t\t\tSystem.out.println(Thread.currentThread().getName() + \"\" + count);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent02/T2.java",
    "content": "package com.mark.concurrent02;\n\n/**\n * synchronized 对类加锁\n * @author MarkShen\n */\npublic class T2 implements Runnable {\n\n\tprivate static int count = 10;\n\n\t@Override\n\tpublic void run() {\n\t\t// lock current object.\n\t\tsynchronized(T2.class) {\n\t\t\tcount --;\n\t\t\tSystem.out.println(Thread.currentThread().getName() + \"\" + count);\n\t\t}\n\t}\n\n\tpublic static void main(String[] args) {\n\t\tfor (int i=0; i<10; i++) {\n\t\t\tnew Thread(new T2(), \"thread\" + i + \"-\").start();\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent03/T.java",
    "content": "package com.mark.concurrent03;\n\n/**\n * synchronized 对对象加锁\n * 加锁位置：堆内存对象\n * @author MarkShen\n */\npublic class T {\n\n\tprivate int count = 10;\n\t\n\tpublic synchronized void m() { // 等同于 synchronized(this)， 锁定当前对象\n\t\tcount --;\n\t\tSystem.out.println(Thread.currentThread().getName() + \"\" + count);\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent04/T.java",
    "content": "package com.mark.concurrent04;\n\n/**\n * synchronized\n * 对对象加锁\n * @author MarkShen\n */\npublic class T {\n\n\tprivate static int count = 10;\n\t\n\tpublic synchronized static void m() { // 等同于synchronized(com.mark.concurrent04.T.class)\n\t\tcount --;\n\t\tSystem.out.println(Thread.currentThread().getName() + \"\" + count);\n\t}\n\t\n\tpublic static void mm() {\n\t\tsynchronized (T.class) { // 考虑下，这里写synchronized(this)是否可以？ 不可以， 因为静态方法，变量是不需要new出对象就可以访问的\n\t\t\tcount --;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent05/T.java",
    "content": "package com.mark.concurrent05;\n\n/**\n * 分析下输出结果\n * @author MarkShen\n */\npublic class T implements Runnable {\n\n\tprivate static int count = 10;\n\n\t@Override\n\tpublic /* synchronized */ void run() { // 等同于synchronized(com.mark.concurrent05.T.class)， 原子操作\n\t\tcount --;\n\t\tSystem.out.println(Thread.currentThread().getName() + \" count= \" + count);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tfor (int i = 0; i < 5; i++) {\n\t\t\tnew Thread(t, \"Thread\" + i).start();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent06/T.java",
    "content": "package com.mark.concurrent06;\n\n/**\n * synchronized 对对象加锁\n * @author MarkShen\n */\npublic class T implements Runnable {\n\n\tprivate static int count = 10;\n\n\t@Override\n\tpublic synchronized void run() { // 等同于synchronized(com.mark.concurrent06.T.class)， 原子操作\n\t\tcount --;\n\t\tSystem.out.println(Thread.currentThread().getName() + \" count= \" + count);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tfor (int i = 0; i < 5; i++) {\n\t\t\tnew Thread(t, \"Thread\" + i).start();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent06/T2.java",
    "content": "package com.mark.concurrent06;\n\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * synchronized AtomicInteger\n * @author MarkShen\n */\npublic class T2 implements Runnable {\n\n\tprivate static AtomicInteger count = new AtomicInteger(10);  // 原子操作，不会出现同样结果\n\n\t@Override\n\tpublic void run() { // 等同于synchronized(com.mark.concurrent06.T.class)， 原子操作\n\t\tint andDecrement = count.getAndDecrement();\n\t\tSystem.out.println(Thread.currentThread().getName() + \" count= \" + andDecrement);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT2 t = new T2();\n\t\tfor (int i = 0; i < 5; i++) {\n\t\t\tnew Thread(t, \"Thread\" + i).start();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent07/T.java",
    "content": "package com.mark.concurrent07;\n\n/**\n * synchronized 对方法加锁, 同步方法和非同步方法是否可以同时调用\n * 在执行m1的过程之中，能否执行m2?\n * 同步方法执行时， 非同步方法可以执行\n * @author MarkShen\n */\npublic class T {\n\n\tpublic synchronized void m1() {\n\t\tSystem.out.println(Thread.currentThread().getName() + \"m1 start...\");\n\t\ttry {\n\t\t\tThread.sleep(10000);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tSystem.out.println(Thread.currentThread().getName() + \"m1 end...\");\n\t}\n\n\tpublic void m2() {\n\t\ttry {\n\t\t\tThread.sleep(5000);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tSystem.out.println(Thread.currentThread().getName() + \"m2 ...\");\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\t\n\t\tnew Thread(() -> t.m1(), \"t1\").start();\n\t\tnew Thread(() -> t.m2(), \"t2\").start();\n\t\t\n//\t\tnew Thread(t::m1, \"t1\").start();\n//\t\tnew Thread(t::m2, \"t2\").start();\n\n\t\t/**\n\t\tnew Thread(new Runnable() {\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t\t\tt.m1();\n\t\t\t}\n\t\t}).start();\n\n\t\tnew Thread(new Runnable() {\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t\t\tt.m2();\n\t\t\t}\n\t\t}).start();\n\t\t */\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent08/Account.java",
    "content": "package com.mark.concurrent08;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 对业务写方法加锁\n * 对业务读方法不加锁\n * 容易产生脏读问题(dirty read) CopyOnWrite, 允不允许脏读? 根据实际业务场景斟酌使用。\n * https://www.cnblogs.com/phoebus0501/archive/2011/02/28/1966709.html\n * @author MarkShen\n */\npublic class Account {\n\tString name;\n\tdouble balance;\n\t\n\tpublic synchronized void set(String name, double balance) {\n\t\tthis.name = name;\n\t\t\n\t\ttry {\n\t\t\tThread.sleep(2000);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\tthis.balance = balance;\n\t}\n\t\n\tpublic /* synchronized */ double getBalance(String name) {\n\t\treturn this.balance;\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tAccount a = new Account();\n\t\tnew Thread(() -> a.set(\"张三\", 100.0)).start();\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\tSystem.out.println(a.getBalance(\"zhangsan\"));\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\tSystem.out.println(a.getBalance(\"zhangsan\"));\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent09/T.java",
    "content": "package com.mark.concurrent09;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 一个同步方法可以调用另一个同步方法。 一个线程已经获得某个对象的锁，再次申请的时候仍然会得到该对象的锁\n * 也就是说synchronized获得的锁是可重入的\n * synchronized 锁升级： https://blog.csdn.net/tongdanping/article/details/79647337\n * @author MarkShen\n */\npublic class T implements Runnable {\n\n\t@Override\n\tpublic synchronized void run() {\n\t\tSystem.out.println(\"m1 start...\");\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tm2();\n\t}\n\t\n\tsynchronized void m2() {\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tSystem.out.println(\"m2\");\n\t}\n\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tnew Thread(t::run).start();\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent10/T.java",
    "content": "package com.mark.concurrent10;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 这里是继承中可能发生的情形，子类调用父类的同步方法， 锁定同一对象\n * @author MarkShen\n */\npublic class T {\n\tsynchronized void m1() {\n\t\tSystem.out.println(\"m1 start...\");\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tSystem.out.println(\"m1 end...\");\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tnew TT().m1();\n\t}\n}\n\nclass TT extends T {\n\t@Override\n\tsynchronized void m1() {\n\t\tSystem.out.println(\"child m1 start...\");\n\t\tsuper.m1();\n\t\tSystem.out.println(\"child m1 end...\");\n\t}\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent11/T.java",
    "content": "package com.mark.concurrent11;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 程序在执行过程中， 如果出现异常， 默认情况锁会被释放\n * 所以，在并发处理的过程中，有异常要多加小心， 不然可能会发生不一致的情况\n * 比如， 在一个App web处理过程中， 多个servlet线程共同访问同一资源，这时如果异常处理不合适，\n * 在第一个线程中抛出异常， 其他线程就会进入同步代码区， 有可能会访问到异常产生时的数据。\n * 因此， 要非常小心处理同步业务中的异常\n * @author MarkShen\n */\npublic class T {\n\tint count = 0;\n\tsynchronized void m() {\n\t\tSystem.out.println(Thread.currentThread().getName() + \" start\");\n\t\twhile(true) {\n\t\t\tcount ++;\n\t\t\tSystem.out.println(Thread.currentThread().getName() + \" count= \" + count);\n\t\t\ttry {\n\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\t\n\t\t\tif (count == 5) {\n\t\t\t\tint i = 1 / 0;  // 此处抛出异常， 锁将被释放， 要不想被释放， 加catch，让循环继续\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tRunnable r = new Runnable() {\n\t\t\t\n\t\t\t@Override\n\t\t\tpublic void run() {\n\t\t\t\tt.m();\n\t\t\t}\n\t\t};\n\t\tnew Thread(r, \"t1\").start();\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(3);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tnew Thread(r, \"t2\").start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent12/T.java",
    "content": "package com.mark.concurrent12;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * volatile关键字， 是一个变量在多线程间可见\n * A, B线程都用到一个变量， Java默认是A线程中保留一份copy, 这样如果B线程修改了该变量， 则线程A未必知道。\n * 使用volatile关键字可以使所有线程都会读到变量的修改值\n * \n * 在下面的代码中， running时存在于对内存的t对象中\n * 当线程t1开通的时候， 会把running值从内存中读到t1线程的工作区，在运行中直接使用这个copy，并不会每次都去\n * 读取内存，这样， 当主线程修改running的值后，t1线程感知不到， 所以不会停止运行。\n * \n * 使用volatile, 将会强制所有线程都去对内存中读取running的值, 缓存过期通知\n * \n * 深入理解请阅读：http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html\n * \n * volatile并不能保证多个线程共同修改running变量时所带来的不一致问题， 也就是说volatile不能代替synchronized\n * \n * Java线程处理的内存模型， 深入了解《深入Java虚拟机》 JMM\n * JDK 并发容器， 能用volatile的地方，就不要用锁\n * @author MarkShen\n *\n */\npublic class T {\n\t/**\n\t * https://www.cnblogs.com/Mushrooms/p/5151593.html\n\t *\n\t * 补充内容：分享点儿知识，内容就是CPU内部的寄存器。就这个程序来说，有两个线程。一个是主线程，\n\t * 一个是自己启动的线程。当自己启动的线程运行时，running这个变量的值会被CPU把值从内存中读到\n\t * CPU中的寄存器(即CPU中的cache)中。为什么这么做呢？因为CPU的速度要比内存的速度快，内存的速\n\t * 度比硬盘快。所以要把running中的数据copy一份到内存中处理。但是，没有加volatile关键字的变\n\t * 量running，当主线程已经把running改为false，自己启动的线程依然不能停下来。因为它读的是CPU\n\t * 中running。主线程改的内存中的running。两个线程读写的变量的存储位置不同。\n\t *\n\t * 而volatile关键字就是为了解决这个问题而出现的。其作用是，当主线程对内存中的变量running修改\n\t * 后，就会通知CPU中的变量running，你那个值已经不是最新的了。这时候，自己启动的线程会重新读一\n\t * 遍内存中的running变量。\n\t */\n\t// volatile 解决了线程间的可见性（观察者模式）\n\tvolatile boolean running = true;  // 对比一下有无volatile情况下， 整个程序运行的结果\n\tvoid m() {\n\t\tSystem.out.println(\"m start\");\n\t\twhile(running) {\n//\t\t\ttry {\n//\t\t\t\tTimeUnit.SECONDS.sleep(1);\n//\t\t\t} catch (InterruptedException e) {\n//\t\t\t\te.printStackTrace();\n//\t\t\t}\n\t\t}\n\t\tSystem.out.println(\"m end\");\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tnew Thread(t::m, \"t1\").start();\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\tt.running = false;\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent13/T.java",
    "content": "package com.mark.concurrent13;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * volatile\t并不能保证多个线程共同修改running变量时所带来的不一致问题，也就是说volatile不能\n * 代替synchronized运行下面的程序， 并分析结果。\n *\n * volatile与synchronized关键字区别？\n * volatile 只能保证可见性，效率高\n * synchronized 既保证可见性，又保证原子性，效率低\n * @author MarkShen\n */\npublic class T {\n\tvolatile int count = 0;\n\tvoid m() {\n\t\tfor (int i = 0; i < 10000; i++) {\n\t\t\tcount ++;\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tList<Thread> threads = new ArrayList<>();\n\t\t\n\t\tfor (int i = 0; i < 10; i ++) {\n\t\t\tthreads.add(new Thread(t::m, \"thread-\" + i));\n\t\t}\n\t\t\n\t\tthreads.forEach((o) -> o.start());\n\t\t\n\t\tthreads.forEach((o) -> {\n\t\t\ttry {\n\t\t\t\to.join();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t});\n\t\t\n\t\tSystem.out.println(t.count);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent14/T.java",
    "content": "package com.mark.concurrent14;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 对比上一个程序，可以用synchronized解决， synchronized既保证原子性，又保证可见性；\n * 而volatile只保证可见性\n * @author MarkShen\n */\npublic class T {\n\t/*volatile*/ int count = 0;\n\tsynchronized void m() {\n\t\tfor (int i = 0; i < 10000; i++) {\n\t\t\tcount ++;\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tList<Thread> threads = new ArrayList<Thread>();\n\t\t\n\t\tfor (int i = 0; i < 10; i ++) {\n\t\t\tthreads.add(new Thread(t::m, \"thread-\" + i));\n\t\t}\n\t\t\n\t\tthreads.forEach((o) -> o.start());\n\t\t\n\t\tthreads.forEach((o) -> {\n\t\t\ttry {\n\t\t\t\to.join();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t});\n\t\t\n\t\tSystem.out.println(t.count);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent15/T.java",
    "content": "package com.mark.concurrent15;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n/**\n * 解决同样的问题更高效的方法，使用AtomicXXX类\n * AtomXXX类本身方法都是原子性的， 但不能保证多方法连续调用的原子性。\n * @author MarkShen\n */\npublic class T {\n\t/*volatile int count = 0;*/\n\t\n\tAtomicInteger count = new AtomicInteger(0);\n\t\n\t/*synchronized*/ void m() {\n\t\tfor (int i = 0; i < 10000; i++) {\n\t\t\t// if (count.get() < 1000)\n\t\t\t// 这个位置没有原子性\n\t\t\tcount.incrementAndGet(); // 替换 count ++;\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tList<Thread> threads = new ArrayList<Thread>();\n\t\t\n\t\tfor (int i = 0; i < 10; i ++) {\n\t\t\tthreads.add(new Thread(t::m, \"thread-\" + i));\n\t\t}\n\t\t\n\t\tthreads.forEach((o) -> o.start());\n\t\t\n\t\tthreads.forEach((o) -> {\n\t\t\ttry {\n\t\t\t\to.join();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t});\n\t\t\n\t\tSystem.out.println(t.count);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent16/T.java",
    "content": "package com.mark.concurrent16;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * synchronized的优化\n * 同步代码中的语句越少越好\n * 比较m1和m2\n * @author MarkShen\n */\npublic class T {\n\t\n\tint count = 0;\n\t\n\tsynchronized void m1() {\n\t\t// do something need not sync\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t// 业务逻辑中只有下面这句需要sync，这时不应该给整个方法上锁\n\t\tcount ++;\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t\n    void m2() {\n\t\t// do something need not sync\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t// 业务逻辑中只有下面这句需要sync，这时不应该给整个方法上锁\n\t\t// 采用细粒度的锁， 可以使用线程争用时间变短，从而提高效率\n\t\tsynchronized(this) {\n\t\t\tcount ++;\n\t\t}\n\t\t// do something need not sync\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\tList<Thread> threads = new ArrayList<Thread>();\n\t\t\n\t\tfor (int i = 0; i < 10; i ++) {\n\t\t\tthreads.add(new Thread(t::m1, \"thread-\" + i));\n\t\t}\n\t\t\n\t\tthreads.forEach((o) -> o.start());\n\t\t\n\t\tthreads.forEach((o) -> {\n\t\t\ttry {\n\t\t\t\to.join();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t});\n\t\t\n\t\tSystem.out.println(t.count);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent17/T.java",
    "content": "package com.mark.concurrent17;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 锁定某对象o， 如果o的属性发生改变，不影响锁的使用\n * 但如果o变成另外一个对象，则锁定的对象发生改变\n * 应该避免将锁定对象的引用变成另外的对象\n * 锁在堆内存new出来的对象\n * @author MarkShen\n */\npublic class T {\n\t\n\tObject o = new Object();\n\t\n\tvoid m() {\n\t\tsynchronized(o) {\n\t\t\twhile (true) {\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tSystem.out.println(Thread.currentThread().getName());\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tT t = new T();\n\t\t\n\t\t// start first thread\n\t\tnew Thread(t::m, \"t1\").start();\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(3);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\t// create second thread\n\t\tThread t2 = new Thread(t::m, \"t2\"); // 锁对象发生改变，所以t2线程得以执行\n\t\tt.o = new Object(); // 如果注释掉这句话，线程2将永远得不到执行\n\t\tt2.start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent18/T.java",
    "content": "package com.mark.concurrent18;\n\n/**\n * 不要以字符串常量作为锁定对象\n * 在下面的例子中，m1和m2其实锁定的是同一对象\n * 这种情况还会发生比较诡异的现象，比如你用到一个类库，在该类库中代码锁定了字符串  \"Hello\"\n * 但是你都不到源码，所以你在自己源码中也锁定了 \"Hello\", 这时就会发生非常诡异的死锁阻塞，\n * 因为你的程序和使用到的类库不经意间使用了同一把锁\n * \n * jetty open source software.\n * \n * @author MarkShen\n */\npublic class T {\n\t\n\tString s1 = \"Hello\";\n\tString s2 = \"Hello\";\n\t\n\tvoid m1() {\n\t\tsynchronized (s1) {\n\t\t\t\n\t\t}\n\t}\n\t\n\tvoid m2() {\n\t\tsynchronized (s2) {\n\t\t\t\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent19/MyContainer1.java",
    "content": "package com.mark.concurrent19;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 曾经的面试题(淘宝?)\n * 实现一个程序，提供两个方法， add, size\n * 写两个线程，线程一添加10个元素到容器中，线程2实现监控线程的个数，\n * 当个数到5个时，线程2给出提示并结束\n * \n * 分析下面的程序，能完成这个功能吗？\n * @author MarkShen\n */\npublic class MyContainer1 {\n\t\n\tList list = new ArrayList();\n\t\n\tpublic void add(Object o) {\n\t\tlist.add(o);\n\t}\n\t\n\tpublic int size() {\n\t\treturn list.size();\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tMyContainer1 c = new MyContainer1();\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tfor(int i=0; i<10; i++) {\n\t\t\t\tc.add(new Object());\n\t\t\t\tSystem.out.println(\"add\" + i);\n\t\t\t\t\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t}, \"t1\").start();\n\t\t\n\t\tnew Thread(() ->{ \n\t\t\twhile(true) {\n\t\t\t\tif (c.size() == 5) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tSystem.out.println(\"Thread2 finished...\");\n\t\t}, \"t2\").start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent19/MyContainer2.java",
    "content": "package com.mark.concurrent19;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 曾经的面试题(淘宝?)\n * 实现一个程序，提供两个方法， add, size\n * 写两个线程，线程一添加10个元素到容器中，线程2实现监控线程的个数，\n * 当个数到5个时，线程2给出提示并结束\n * \n * 添加volatile，使t2可以得到通知， 但是，t2线程的死循环很浪费CPU, 如果不用死循环该怎么做？\n * 面试题要比你的竞争者好， 比别人牛，面试不是及格就好，面试要拿到100分，110分，120分。总之，要与众不同\n * 怎么展现自己（重要）\n *\n * 问题：\n * 不是很精确\n * 浪费CPU资源\n * @author MarkShen\n */\npublic class MyContainer2 {\n\t\n\t// 添加volatile，使t2可以得到通知\n\tvolatile List list = new ArrayList();\n\t\n\tpublic void add(Object o) {\n\t\tlist.add(o);\n\t}\n\t\n\tpublic int size() {\n\t\treturn list.size();\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tMyContainer2 c = new MyContainer2();\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tfor(int i=0; i<10; i++) {\n\t\t\t\tc.add(new Object());\n\t\t\t\tSystem.out.println(\"add\" + i);\n\t\t\t\t\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t}, \"t1\").start();\n\t\t\n\t\tnew Thread(() ->{ \n\t\t\twhile(true) {\n\t\t\t\tif (c.size() == 5) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tSystem.out.println(\"Thread2 finished...\");\n\t\t}, \"t2\").start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent19/MyContainer3.java",
    "content": "package com.mark.concurrent19;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 曾经的面试题(淘宝?)\n * 实现一个程序，提供两个方法， add, size\n * 写两个线程，线程一添加10个元素到容器中，线程2实现监控线程的个数，\n * 当个数到5个时，线程2给出提示并结束\n *\n * 添加volatile，使t2可以得到通知， 但是，t2线程的死循环很浪费CPU, 如果不用死循环该怎么做？\n * 面试题要比你的竞争者好， 比别人牛\n * 怎么展现自己（重要）\n *\n * 这里使用wait和notify做到， wait会释放锁， 而notify不会释放锁(被锁定对象的wait和notify方法)\n * 需要注意的是，运用这种方法，必须保证t2先执行，先让t2监听才可以\n * \n * 阅读线面程序给出结果\n * 可以读到输出结果并不是size==5时， t2退出， 而是t1结束时通知t2才收到通知而退出\n * 想想为什么？？？\n * notify不会释放锁， sleep也不释放锁\n * @author MarkShen\n */\npublic class MyContainer3 {\n\t\n\t// 添加volatile，使t2可以得到通知\n\tvolatile List list = new ArrayList();\n\t\n\tpublic void add(Object o) {\n\t\tlist.add(o);\n\t}\n\t\n\tpublic int size() {\n\t\treturn list.size();\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tMyContainer3 c = new MyContainer3();\n\t\t\n\t\tfinal Object lock = new Object();\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tsynchronized(lock) {\n\t\t\t\tSystem.out.println(\"t2 启动\");\n\t\t\t\tif (c.size() != 5) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlock.wait();\n\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tSystem.out.println(\"t2 结束\");\n\t\t\t}\n\t\t}, \"t2\").start();\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tsynchronized(lock) {\n\t\t\t\tfor (int i=0; i<10; i++) {\n\t\t\t\t\tc.add(new Object());\n\t\t\t\t\tSystem.out.println(\"add \" + i);\n\t\t\t\t\t\n\t\t\t\t\tif (c.size() == 5) {\n\t\t\t\t\t\tlock.notify();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, \"t1\").start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent19/MyContainer4.java",
    "content": "package com.mark.concurrent19;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 曾经的面试题(淘宝?)\n * 实现一个程序，提供两个方法， add, size\n * 写两个线程，线程一添加10个元素到容器中，线程2实现监控线程的个数，\n * 当个数到5个时，线程2给出提示并结束\n * \n * 添加volatile，使t2可以得到通知， 但是，t2线程的死循环很浪费CPU, 如果不用死循环该怎么做？\n * 面试题要比你的竞争者好， 比别人牛\n * 怎么展现自己（重要）\n * \n * 这里使用wait和notify做到， wait会释放锁， 而notify不会释放锁(被锁定对象的wait和notify方法)\n * 需要注意的是，运用这种方法，必须保证t2先执行，先让t2监听才可以\n * \n * 阅读线面程序给出结果\n * 可以读到输出结果并不是size==5时， t2退出， 而是t1结束时通知t2才收到通知而退出\n * 想想为什么？？？\n * notify不会释放锁， sleep也不释放锁\n * \n * notify之后，t1必须释放锁， t2退出后，也必须notify, 通知t1继续执行， 整个通信过程比较繁琐\n * @author MarkShen\n */\npublic class MyContainer4 {\n\t\n\t// 添加volatile，使t2可以得到通知\n\tvolatile List list = new ArrayList();\n\t\n\tpublic void add(Object o) {\n\t\tlist.add(o);\n\t}\n\t\n\tpublic int size() {\n\t\treturn list.size();\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tMyContainer4 c = new MyContainer4();\n\t\t\n\t\tfinal Object lock = new Object();\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tsynchronized(lock) {\n\t\t\t\tSystem.out.println(\"t2 启动\");\n\t\t\t\tif (c.size() != 5) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlock.wait();\n\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// 通知t1继续执行\n\t\t\t\tlock.notify();\n\t\t\t\tSystem.out.println(\"t2 结束\");\n\t\t\t}\n\t\t}, \"t2\").start();\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tsynchronized(lock) {\n\t\t\t\tfor (int i=0; i<10; i++) {\n\t\t\t\t\tc.add(new Object());\n\t\t\t\t\tSystem.out.println(\"add \" + i);\n\t\t\t\t\t\n\t\t\t\t\tif (c.size() == 5) {\n\t\t\t\t\t\tlock.notify();\n\t\t\t\t\t\t// 释放锁，让t2得以执行\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tlock.wait();\n\t\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, \"t1\").start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent19/MyContainer5.java",
    "content": "package com.mark.concurrent19;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 曾经的面试题(淘宝?)\n * 实现一个程序，提供两个方法， add, size\n * 写两个线程，线程一添加10个元素到容器中，线程2实现监控线程的个数，\n * 当个数到5个时，线程2给出提示并结束\n * \n * 添加volatile，使t2可以得到通知， 但是，t2线程的死循环很浪费CPU, 如果不用死循环该怎么做？\n * 面试题要比你的竞争者好， 比别人牛\n * 怎么展现自己（重要）\n * \n * 这里使用wait和notify做到， wait会释放锁， 而notify不会释放锁(被锁定对象的wait和notify方法)\n * 需要注意的是，运用这种方法，必须保证t2先执行，先让t2监听才可以\n * \n * 阅读线面程序给出结果\n * 可以读到输出结果并不是size==5时， t2退出， 而是t1结束时通知t2才收到通知而退出\n * 想想为什么？？？\n * notify不会释放锁， sleep也不释放锁\n * \n * notify之后，t1必须释放锁， t2退出后，也必须notify, 通知t1继续执行， 整个通信过程比较繁琐\n * \n * 使用Latch（门闩）代替wait, notify来进行通知\n * 好处通信方式简单， 同时可以指定等待时间\n * 使用await和countdown方法来代替wait, notify\n * CountDownLatch不涉及锁定，当count的值为0时当前线程继续运行\n * 当不涉及同步，只有涉及线程通信的时候，用synchronized + wait/notify就太重了\n * 这时应该考虑使用CountDownLatch/cyclicbarrier/semaphore\n * \n * @author MarkShen\n */\npublic class MyContainer5 {\n\t\n\t// 添加volatile，使t2可以得到通知\n\tvolatile List list = new ArrayList();\n\t\n\tpublic void add(Object o) {\n\t\tlist.add(o);\n\t}\n\t\n\tpublic int size() {\n\t\treturn list.size();\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tMyContainer5 c = new MyContainer5();\n\t\t\n\t\tCountDownLatch latch = new CountDownLatch(1);\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tSystem.out.println(\"t2 启动\");\n\t\t\tif (c.size() != 5) {\n\t\t\t\ttry {\n\t\t\t\t\tlatch.await();\n\t\t\t\t\t// 可以指定等待时间\n\t\t\t\t\t// latch.await(5000, TimeUnit.MILLISECONDS)\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t\tSystem.out.println(\"t2 结束\");\n\t\t}, \"t2\").start();\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\tnew Thread(() -> {\n\t\t\tfor (int i=0; i<10; i++) {\n\t\t\t\tc.add(new Object());\n\t\t\t\tSystem.out.println(\"add \" + i);\n\t\t\t\t\n\t\t\t\tif (c.size() == 5) {\n\t\t\t\t\t// 打开门闩，让t2得以执行\n\t\t\t\t\tlatch.countDown();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\n\t\t}, \"t1\").start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent20/ReentrantLock1.java",
    "content": "package com.mark.concurrent20;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * reentrantlock用于代替synchronized\n * 本例中由于m1锁定this, 只有m1执行完毕的时候， m2才能执行\n * 这里是复制synchronized最原始的语义\n * \n * @author MarkShen\n */\npublic class ReentrantLock1 {\n\tsynchronized void m1() {\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\ttry {\n\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tSystem.out.println(Thread.currentThread().getName() + i);\n\t\t}\n\t}\n\t\n\tsynchronized void m2() {\n\t\tSystem.out.println(\"m2......\");\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tReentrantLock1 r1 = new ReentrantLock1();\n\t\tnew Thread(r1::m1).start();\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tnew Thread(r1::m2).start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent20/ReentrantLock2.java",
    "content": "package com.mark.concurrent20;\n\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * 使用reentrantlock可以完成相同的功能\n * 需要注意的是，必须要必须要必须要手动释放锁\n * 使用synchronized锁定的话如果遇到异常，JVM会自动释放锁，但是lock必须手动释放锁，\n * 因此经常在finally中进行锁的释放\n * @author MarkShen\n */\npublic class ReentrantLock2 {\n\tLock lock = new ReentrantLock();\n\tvoid m1() {\n\t\tlock.lock();  // synchronized(this)\n\t\ttry {\n\t\t\tfor (int i = 0; i < 10; i++) {\n\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\tSystem.out.println(i);\n\t\t\t}\n\t\t} catch (InterruptedException e1) {\n\t\t\te1.printStackTrace();\n\t\t} finally {\n\t\t\tlock.unlock();\n\t\t}\n\t\t\n\t}\n\t\n\tvoid m2() {\n\t\tlock.lock();\n\t\tSystem.out.println(\"m2......\");\n\t\tlock.unlock();\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tReentrantLock2 r1 = new ReentrantLock2();\n\t\tnew Thread(r1::m1).start();\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tnew Thread(r1::m2).start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent20/ReentrantLock3.java",
    "content": "package com.mark.concurrent20;\n\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * 使用reentrantlock可以进行尝试锁定\"tryLock\", 这样无法锁定，或者在指定时间内无法锁定，\n * 线程可以决定是否继续等待\n *\n * @author MarkShen\n */\npublic class ReentrantLock3 {\n\tLock lock = new ReentrantLock();\n\tvoid m1() {\n\t\tlock.lock();  // synchronized(this)\n\t\ttry {\n\t\t\tfor (int i = 0; i < 10; i++) {\n\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\tSystem.out.println(i);\n\t\t\t}\n\t\t} catch (InterruptedException e1) {\n\t\t\te1.printStackTrace();\n\t\t} finally {\n\t\t\tlock.unlock();\n\t\t}\n\t\t\n\t}\n\t\n\t/**\n\t * 使用tryLock进行尝试锁定，不过锁定与否，方法都将继续执行\n\t * 可根据tryLock的返回值来确定是否锁定\n\t * 也可以指定tryLock的时间，有tryLock(time)抛出异常，\n\t * 所以要注意unlock的处理必须放到finally中\n\t */\n\tsynchronized void m2() {\n\t\t// 如果锁定了怎么办， 没锁定怎么办， 逻辑根据返回值来判断\n\t\t/*boolean locked = lock.tryLock();\n\t\tSystem.out.println(\"m2......\" + locked);\n\t\tif (locked) lock.unlock();*/\n\t\t\n\t\tboolean locked = lock.tryLock();\n\t\ttry {\n\t\t\tlocked = lock.tryLock(5, TimeUnit.SECONDS);\n\t\t\tSystem.out.println(\"m2......\" + locked);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t} finally {\n\t\t\tif (locked) lock.unlock();\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tReentrantLock3 r1 = new ReentrantLock3();\n\t\tnew Thread(r1::m1).start();\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tnew Thread(r1::m2).start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent20/ReentrantLock4.java",
    "content": "package com.mark.concurrent20;\n\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * 使用reentrantlock可以调用lockInterruptibly方法，可以对线程interrupt方法做出响应，\n * 在一个线程中等待锁的过程中， 可能被打断\n * \n * @author MarkShen\n *\n */\npublic class ReentrantLock4 {\n\t\n\tpublic static void main(String[] args) {\n\t\tLock lock = new ReentrantLock();\n\t\t\n\t\tThread t1 = new Thread(() -> {\n\t\t\tlock.lock();  // synchronized(this)\n\t\t\ttry {\n\t\t\t\tSystem.out.println(\"t1 start\");\n\t\t\t\tTimeUnit.SECONDS.sleep(Integer.MAX_VALUE);\n\t\t\t\tSystem.out.println(\"t1 end\");\n\t\t\t} catch (InterruptedException e1) {\n\t\t\t\te1.printStackTrace();\n\t\t\t} finally {\n\t\t\t\tlock.unlock();\n\t\t\t}\n\t\t});\n\t\tt1.start();\n\t\t\n\t\tThread t2 = new Thread(() -> {\n\t\t\tboolean locked = false; // 防止异常抛出\n\t\t\ttry {\n\t\t\t\t// lock.lock();  // synchronized(this)\n\t\t\t\tlock.lockInterruptibly();  // 可对interrupt()方法做出响应\n\t\t\t\t// 防止异常抛出\n\t\t\t\tlocked = lock.tryLock();\n\t\t\t\tSystem.out.println(\"t2 start\");\n\t\t\t\tTimeUnit.SECONDS.sleep(Integer.MAX_VALUE);\n\t\t\t\tSystem.out.println(\"t2 end\");\n\t\t\t} catch (InterruptedException e1) {\n\t\t\t\tSystem.out.println(\"interrupted...\");\n\t\t\t} finally {\n\t\t\t\tif (locked) lock.unlock();\n\t\t\t}\n\t\t});\n\t\tt2.start();\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tt2.interrupt(); // Interrupts this thread.\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent20/ReentrantLock5.java",
    "content": "package com.mark.concurrent20;\n\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * reentrantlock还可以指定为公平锁，默认的synchronized为非公平锁\n * 谁等的时间长，谁获得锁\n * Java 线程调度器\n * @author MarkShen\n */\npublic class ReentrantLock5 extends Thread {\n\t\n\tprivate ReentrantLock lock = new ReentrantLock(true); // 参数为true为公平锁，请对比输入结果\n\t\n\t@Override\n\tpublic void run() {\n\t\tfor (int i = 0; i < 100; i++) {\n\t\t\tlock.lock();\n\t\t\ttry {\n\t\t\t\tSystem.out.println(Thread.currentThread().getName() + \"获得锁\");\n\t\t\t} finally {\n\t\t\t\tlock.unlock();\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tReentrantLock5 r1 = new ReentrantLock5();\n\t\tThread t1 = new Thread(r1);\n\t\tThread t2 = new Thread(r1);\n\t\tt1.start();\n\t\tt2.start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent21/MyContainer1.java",
    "content": "package com.mark.concurrent21;\n\nimport java.util.LinkedList;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 面试题\n * 写一个固定容量同步容器， 拥有put,get方法，以及getCount方法\n * 能够支持2个生产线程， 10个消费线程的阻塞调用\n * \n * 使用wait和notify/notifyAll来实现\n * Effective Java: wait 往往与 while一起使用\n * \n * @author MarkShen\n *\n */\npublic class MyContainer1<T> {\n\t\n\tfinal private LinkedList<T> lists = new LinkedList<>();\n\tfinal private int MAX = 10; // 最多是个元素\n\tprivate int count = 0;\n\t\n\tpublic synchronized void put(T t) {\n\t\twhile (lists.size() == MAX) { // 为什么要用while， 不用if?\n\t\t\t/**\n\t\t\t * 两个以上线程的时候\n\t\t\t */\n\t\t\ttry {\n\t\t\t\tthis.wait();  // 释放锁\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\t\n\t\tlists.add(t);\n\t\t++ count;\n\t\tthis.notifyAll();  // 通知消费者线程进行消费\n\t}\n\t\n\tpublic synchronized T get() {\n\t\tT t = null;\n\t\twhile (lists.size() == 0) { // 为什么要用while， 不用if?\n\t\t\ttry {\n\t\t\t\tthis.wait();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t\t\n\t\tt = lists.removeFirst();\n\t\t-- count;\n\t\tthis.notifyAll();  // 通知生产者线程进行生产\n\t\treturn t;\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tMyContainer1<String> c = new MyContainer1<String>();\n\t\t// start consumer thread\n\t\tfor (int i = 0; i < 10; i ++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\tfor (int j = 0; j < 5; j++) {\n\t\t\t\t\tSystem.out.println(c.get());\n\t\t\t\t}\n\t\t\t}, \"c\" + i).start();\n\t\t}\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\t// start producer thread\n\t\tfor (int i = 0; i < 2; i ++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\tfor (int j = 0; j < 25; j++) {\n\t\t\t\t\tc.put(Thread.currentThread().getName() + \" \" + j);\n\t\t\t\t}\n\t\t\t}, \"p\" + i).start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent21/MyContainer2.java",
    "content": "package com.mark.concurrent21;\n\nimport java.util.LinkedList;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.locks.Condition;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * 面试题\n * 写一个固定容量同步容器， 拥有put,get方法，以及getCount方法\n * 能够支持2个生产线程， 10个消费线程的阻塞调用\n * \n * Effective Java: wait 往往与 while一起使用\n * \n * 使用Lock和Condition来实现\n * 对比两种方式，Condition的方式可以更加精确的指定哪些线程被唤醒\n * \n * @author MarkShen\n */\npublic class MyContainer2<T> {\n\t\n\tfinal private LinkedList<T> lists = new LinkedList<>();\n\tfinal private int MAX = 10; // 最多是个元素\n\tprivate int count = 0;\n\t\n\tprivate Lock lock = new ReentrantLock();\n\t// 精确指定\n\tprivate Condition producer = lock.newCondition();\n\tprivate Condition consumer = lock.newCondition();\n\t\n\tpublic void put(T t) {\n\t\ttry {\n\t\t\tlock.lock();\n\t\t\twhile (lists.size() == MAX) { // 为什么要用while， 不用if?\n\t\t\t\tproducer.await();\n\t\t\t}\n\t\t\t\n\t\t\tlists.add(t);\n\t\t\t++ count;\n\t\t\tconsumer.signalAll();  // 通知消费者线程进行消费\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t} finally {\n\t\t\tlock.unlock();\n\t\t}\n\t}\n\t\n\tpublic T get() {\n\t\tT t = null;\n\t\ttry {\n\t\t\tlock.lock();\n\t\t\twhile (lists.size() == 0) { // 为什么要用while， 不用if?\n\t\t\t\tconsumer.await();\n\t\t\t}\n\t\t\t\n\t\t\tt = lists.removeFirst();\n\t\t\t++ count;\n\t\t\tproducer.signalAll();  // 通知消费者线程进行消费\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t} finally {\n\t\t\tlock.unlock();\n\t\t}\n\t\treturn t;\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tMyContainer2<String> c = new MyContainer2<String>();\n\t\t// start consumer thread\n\t\tfor (int i = 0; i < 10; i ++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\tfor (int j = 0; j < 5; j++) {\n\t\t\t\t\tSystem.out.println(c.get());\n\t\t\t\t}\n\t\t\t}, \"c\" + i).start();\n\t\t}\n\t\t\n\t\ttry {\n\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\t\n\t\t// start producer thread\n\t\tfor (int i = 0; i < 2; i ++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\tfor (int j = 0; j < 25; j++) {\n\t\t\t\t\tc.put(Thread.currentThread().getName() + \" \" + j);\n\t\t\t\t}\n\t\t\t}, \"p\" + i).start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent22/ThreadLocal1.java",
    "content": "package com.mark.concurrent22;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * \n * @author MarkShen\n */\npublic class ThreadLocal1 {\n\tvolatile static Person p = new Person();\n\t\n\tpublic static void main(String[] args) {\n\t\tnew Thread(() -> {\n\t\t\ttry {\n\t\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\t\n\t\t\tSystem.out.println(p.name);\n\t\t}).start();\n\t\t\n\t\tnew Thread(() -> {\n\t\t\ttry {\n\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\t\n\t\t\tp.name = \"lisi\";\n\t\t}).start();\n\t}\n}\n\nclass Person {\n\tString name = \"zhangsan\";\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent22/ThreadLocal2.java",
    "content": "package com.mark.concurrent22;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * ThreadLocal线程局部变量\n * 空间换时间，synchronized时间换空间\n * 比如Hibernate中session就是存放在ThreadLocal中的， 避免synchronized的使用。\n * \n * 运行下面程序，理解ThreadLocal\n * 在使用的时候，状态改变，自己维护这个状态，不用通知其他线程，这时使用ThreadLocal\n * 可能会导致内存泄漏\n *\n * 使用场景：自己进行改变，自己维护这个状态，不用其他线程\n * https://blog.csdn.net/zsfsoftware/article/details/50933151\n * @author MarkShen\n *\n */\npublic class ThreadLocal2 {\n\t// 每个线程各放一份，修改只改自己的一份， 不会是别人的一份，以空间换时间，效率更高\n\tstatic ThreadLocal<Person> tl = new ThreadLocal<>();\n\tpublic static void main(String[] args) {\n\t\tnew Thread(() -> {\n\t\t\ttry {\n\t\t\t\tTimeUnit.SECONDS.sleep(2);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\t\n\t\t\tSystem.out.println(tl.get());\n\t\t}).start();\n\t\t\n\t\tnew Thread(() -> {\n\t\t\ttry {\n\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\t\n\t\t\ttl.set(new Person());\n\t\t}).start();\n\t}\n\t\n\tstatic class Person {\n\t\tString name = \"zhangsan\";\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent23/Singleton.java",
    "content": "package com.mark.concurrent23;\n\nimport java.util.Arrays;\n\n/**\n * 线程安全的单利模式\n * 最理想的单利模式实现方法\n * @author MarkShen\n */\npublic class Singleton {\n\tprivate Singleton() {}\n\t\n\tprivate static class Inner {\n\t\tprivate static Singleton instance = new Singleton();\n\t}\n\t\n\tpublic static Singleton getInstance() {\n\t\treturn Inner.instance;\n\t}\n\n\tpublic static void main(String[] args) {\n\t\tThread[] threads = new Thread[200];\n\t\tfor (int i=0; i<threads.length; i++) {\n\t\t\tthreads[i] = new Thread(() -> {\n\t\t\t\tSystem.out.println(Singleton.getInstance());\n\t\t\t});\n\t\t}\n\n\t\tArrays.asList(threads).forEach(o -> o.start());\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent24/TicketSeller1.java",
    "content": "package com.mark.concurrent24;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 有n张火车票，每张票都有一编号\n * 同时有10个窗口在对外售票\n * 写一个模拟程序\n * \n * 分析下面程序可能产生那些问题?\n * 重复销售， 超量销售\n * @author MarkShen\n *\n */\npublic class TicketSeller1 {\n\tstatic List<String> tickets = new ArrayList<String>();\n\t\n\tstatic {\n\t\tfor (int i=0; i<10000; i++) tickets.add(\"票编号:\" + i);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tfor (int i=0; i<10; i++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\twhile(tickets.size() > 0) {\n\t\t\t\t\tSystem.out.println(\"销售了--\" + tickets.remove(0));  // remove方法非原子性\n\t\t\t\t}\n\t\t\t}).start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent24/TicketSeller2.java",
    "content": "package com.mark.concurrent24;\n\nimport java.util.Vector;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 有n张火车票，每张票都有一编号\n * 同时有10个窗口在对外售票\n * 写一个模拟程序\n * \n * 分析下面程序可能产生那些问题?\n * 重复销售， 超量销售\n * @author MarkShen\n *\n */\npublic class TicketSeller2 {\n\tstatic Vector<String> tickets = new Vector<String>();  // 本身就是同步容器\n\t\n\tstatic {\n\t\tfor (int i=0; i<10000; i++) tickets.add(\"票编号:\" + i);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tfor (int i=0; i<10; i++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\twhile(tickets.size() > 0) {  // 原子性\n\t\t\t\t\t// 中间部分不是原子性的\n\t\t\t\t\t/*try {\n\t\t\t\t\t\tTimeUnit.SECONDS.sleep(10);\n\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}*/\n\t\t\t\t\tSystem.out.println(\"销售了--\" + tickets.remove(0));  // 原子性\n\t\t\t\t}\n\t\t\t}).start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent24/TicketSeller3.java",
    "content": "package com.mark.concurrent24;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 有n张火车票，每张票都有一编号\n * 同时有10个窗口在对外售票\n * 写一个模拟程序\n * \n * 分析下面程序可能产生那些问题?\n * 没有问题了，但效率不高\n * @author MarkShen\n */\npublic class TicketSeller3 {\n\tstatic List<String> tickets = new ArrayList<String>();\n\t\n\tstatic {\n\t\tfor (int i=0; i<10000; i++) tickets.add(\"票编号:\" + i);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tfor (int i=0; i<10; i++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\twhile (true) {\n\t\t\t\t\tsynchronized(tickets) {\n\t\t\t\t\t\tif (tickets.size() < 0) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tSystem.out.println(\"销售了--\" + tickets.remove(0));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}).start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent24/TicketSeller4.java",
    "content": "package com.mark.concurrent24;\n\nimport java.util.Queue;\nimport java.util.concurrent.ConcurrentLinkedQueue;\n\n/**\n * 有n张火车票，每张票都有一编号\n * 同时有10个窗口在对外售票\n * 写一个模拟程序\n * \n * 分析下面程序可能产生那些问题?\n * 没问题，效率高\n * @author MarkShen\n *\n */\npublic class TicketSeller4 {\n\tstatic Queue<String> tickets = new ConcurrentLinkedQueue<String>();  // Queue里面不应该有空值\n\t\n\tstatic {\n\t\tfor (int i = 0; i < 1000; i ++) tickets.add(\"票编号:\" + i);\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tfor (int i = 0; i < 10; i ++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\twhile(true) {\n\t\t\t\t\tString s = tickets.poll();\n\t\t\t\t\t// 在写if ... else ... 代码的时候，一定要加大括号。下面的代码是反例\n\t\t\t\t\tif (s == null)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse\n\t\t\t\t\t\tSystem.out.println(\"销售了--\" + s);\n\t\t\t\t}\n\t\t\t}).start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T01_ConcurrentMap.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Hashtable;\nimport java.util.Map;\nimport java.util.Random;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ConcurrentSkipListMap;\nimport java.util.concurrent.CountDownLatch;\n\n/**\n * 阅读ConcurrentSkipListMap\n * http://blog.csdn.net/sunxianghuang/article/details/52221913\n *\n * 总结\n * 1. 对于Map/Set的选择与使用\n * \t1) 不加锁（单线程时候）\n * \tHashMap\n * \tTreeMap\n * \tLinkedHashMap\n * \n * \t2) 加锁（多线程场景）\n * \t并发不高\n * \tHashtable\n * \tCollections.synchronizedXXX\n * \n * \t并发高的时候\n * \tConcurrentHashMap\n * \n * \t并发性高且排序\n * \tConcurrentSkipListMap\n * \n * 2. 队列\n * \tArrayList\n * \tLinkedList\n * \tCollections.synchronizedXXX\n * \tCopyOnWriteList\n * \n * \t高并发场景\n * \tConcurrentLinkedQueue // 非阻塞\n * \tBlockingQueue         // 阻塞\n * \t\tLinkedBlockingQueue\n * \t\tArrayBlockingQueue\n * \t\tTransferQueue\n * \t\tSynchronousQueue\n * \tDelayQueue：定时任务\n * \n * @author MarkShen\n */\npublic class T01_ConcurrentMap {\n\t\n\tpublic static void main(String[] args) {\n\t\t// 不同容器在多线程并发下的效率问题\n//\t\tMap<String, String> map = new ConcurrentHashMap<>();\n//\t\tMap<String, String> map = new ConcurrentSkipListMap<>();  // 高并发， 排序\n\t\t\n//\t\tMap<String, String> map = new Hashtable<>();\n\t\tMap<String, String> map = new HashMap<String, String>(); // Collections.synchronizedXXX\n//\t\tTreeMap\n\t\tRandom r = new Random();\n\t\tThread[] threads = new Thread[100];\n\t\tCountDownLatch latch = new CountDownLatch(threads.length);\n\t\t\n\t\tlong start = System.currentTimeMillis();\n\t\tfor (int i=0; i<threads.length; i++) {\n\t\t\tthreads[i] = new Thread(() -> {\n\t\t\t\tfor (int j=0; j<10000; j++) map.put(\"a\" + r.nextInt(100000), \"a\" + r.nextInt(100000));\n\t\t\t\tlatch.countDown();\n\t\t\t});\n\t\t}\n\t\t\n\t\tArrays.asList(threads).forEach(t->t.start());\n\t\ttry {\n\t\t\tlatch.await();\n\t\t} catch (InterruptedException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tlong end = System.currentTimeMillis();\n\t\tSystem.out.println(end - start);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T02_CopyOnWriteList.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Random;\nimport java.util.Vector;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\n/**\n * 写时复制容器 copy on write\n * 多线程下，写效率低， 读效率高\n *\n * 应用场景：适合写少读多的情况\n * \n * @author MarkShen\n */\npublic class T02_CopyOnWriteList {\n\t\n\tpublic static void main(String[] args) {\n\t\tList<String> lists = \n\t\t\t\t\t\t\t// new ArrayList<>(); // 会有并发问题\n\t\t\t\t\t\t\t// new Vector<>();\n\t\t\t\t\t\t\tnew CopyOnWriteArrayList<>(); // 事件监听器的队列\n\t\tRandom r = new Random();\n\t\tThread[] threads = new Thread[100];\n\t\t\n\t\tfor (int i=0; i<threads.length; i++) {\n\t\t\tRunnable task = new Runnable() {\n\t\t\t\t\n\t\t\t\t@Override\n\t\t\t\tpublic void run() {\n\t\t\t\t\tfor (int i=0; i<1000; i++)\n\t\t\t\t\t\tlists.add(\"a\" + r.nextInt(10000));\n\t\t\t\t}\n\t\t\t};\n\t\t\tthreads[i] = new Thread(task);\n\t\t}\n\t\t\n\t\trunAndComputeTime(threads);\n\t\tSystem.out.println(lists.size());\n\t}\n\n\tprivate static void runAndComputeTime(Thread[] threads) {\n\t\tlong start = System.currentTimeMillis();\n\t\tArrays.asList(threads).forEach(t->t.start());\n\t\tArrays.asList(threads).forEach(t->{\n\t\t\ttry {\n\t\t\t\tt.join();\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t});\n\t\tlong end = System.currentTimeMillis();\n\t\tSystem.out.println(end - start);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T03_SynchronizedList.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * @author MarkShen\n */\npublic class T03_SynchronizedList {\n\t\n\tpublic static void main(String[] args) {\n\t\tList<String> strings = new ArrayList<String>();\n\t\t// 加锁的容器\n\t\tList<String> strsSync = Collections.synchronizedList(strings);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T04_ConcurrentQueue.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.Queue;\nimport java.util.concurrent.ConcurrentLinkedQueue;\n\n/**\n * 重点内容，重点掌握\n * @author MarkShen\n */\npublic class T04_ConcurrentQueue {\n\t\n\tpublic static void main(String[] args) {\n\t\tQueue<String> strs = new ConcurrentLinkedQueue<>();  // 无界队列\n\t\t\n\t\tfor (int i=0; i<10; i++) {\n\t\t\tstrs.offer(\"a\" + i);\n\t\t}\n\t\t\n\t\tSystem.out.println(strs);\n\t\t\n\t\tSystem.out.println(strs.poll());\n\t\tSystem.out.println(strs.size());\n\t\t\n\t\tSystem.out.println(strs.peek());\n\t\tSystem.out.println(strs.size());\n\t\t\n\t\t// 双端队列 Deque\n\t\t// 并发容器中常用\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T05_LinkedBlockingQueue.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.Random;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 非常常用\n * Queue分两种：\n *\n * @author MarkShen\n */\npublic class T05_LinkedBlockingQueue {\n\tstatic BlockingQueue<String> strs = new LinkedBlockingQueue<>();  // 非常常用， 无界队列\n\t\n\tstatic Random r = new Random();\n\t\n\tpublic static void main(String[] args) {\n\t\tnew Thread(() -> {\n\t\t\tfor (int i=0; i<100; i++) {\n\t\t\t\ttry {\n\t\t\t\t\tstrs.put(\"a\" + i);  // 如果满了，等会儿\n\t\t\t\t\tTimeUnit.MICROSECONDS.sleep(r.nextInt(1000));\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t}\t\t\t\n\t\t}, \"p1\").start();\n\t\t\n\t\tfor (int i = 0; i < 5; i ++) {\n\t\t\tnew Thread(() -> {\n\t\t\t\tfor (;;) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tSystem.out.println(Thread.currentThread().getName() + \" take - \" + strs.take());  // 如果空了，等待\n\t\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\t\te.printStackTrace();\n\t\t\t\t\t}\n\t\t\t\t}\t\t\t\n\t\t\t}, \"c1\").start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T06_ArrayBlockingQueue.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.Random;\nimport java.util.concurrent.ArrayBlockingQueue;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.TimeUnit;\n\n/**\n *\n * @author MarkShen\n */\npublic class T06_ArrayBlockingQueue {\n\tstatic BlockingQueue<String> strs = new ArrayBlockingQueue<>(10); // 有界队列， 线程池里装的都是一个一个的任务\n\n\tstatic Random r = new Random();\n\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\tfor (int i = 0; i < 10; i++) {\n\t\t\tstrs.put(\"a\" + i);\n\t\t}\n\t\t\n\t\t// strs.put(\"aaa\"); // 满了就等待\n\t\tstrs.add(\"aaa\");\n\t\t// strs.offer(\"aaa\");\n\t\t// strs.offer(\"aaa\", 1, TimeUnit.SECONDS); // 按时间段阻塞\n\t\t\n\t\tSystem.out.println(strs);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T07_DelayQueue.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.Random;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.DelayQueue;\nimport java.util.concurrent.Delayed;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 用于执行定时任务\n * @author MarkShen\n */\npublic class T07_DelayQueue {\n\t// 排好顺序的，等待时间最长的被先拿出去\n\tstatic BlockingQueue<MyTask> tasks = new DelayQueue<>(); // 无界队列， 线程池里装的都是一个一个的任务\n\n\tstatic Random r = new Random();\n\t\n\tstatic class MyTask implements Delayed {\n\t\t\n\t\tlong runningTime;\n\t\t\n\t\tpublic MyTask(long runningTime) {\n\t\t\tthis.runningTime = runningTime;\n\t\t}\n\n\t\t@Override\n\t\tpublic int compareTo(Delayed o) {\n\t\t\tif (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) {\n\t\t\t\treturn -1;\n\t\t\t} else if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\t@Override\n\t\tpublic long getDelay(TimeUnit unit) {\n\t\t\treturn unit.convert(runningTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);\n\t\t}\n\n\t\t@Override\n\t\tpublic String toString() {\n\t\t\treturn \"MyTask [runningTime=\" + runningTime + \"]\";\n\t\t}\n\t}\n\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\tlong now = System.currentTimeMillis();\n\t\tMyTask t1 = new MyTask(now + 1000);\n\t\tMyTask t2 = new MyTask(now + 2000);\n\t\tMyTask t3 = new MyTask(now + 1500);\n\t\tMyTask t4 = new MyTask(now + 2500);\n\t\tMyTask t5 = new MyTask(now + 500);\n\t\t\n\t\ttasks.put(t1);\n\t\ttasks.put(t2);\n\t\ttasks.put(t3);\n\t\ttasks.put(t4);\n\t\ttasks.put(t5);\n\t\t\n\t\tSystem.out.println(tasks);\n\t\t\n\t\tfor (int i = 0; i < 5; i ++) {\n\t\t\tSystem.out.println(tasks.take());\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T08_TransferQueue.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.concurrent.LinkedTransferQueue;\n\n/**\n * 用在更高的并发的情况下，实时消息处理\n * 消费者先起来， 生产者直接找消费者， 如果有消费者，直接把数据给消费者\n * \n * 1) 先启动消费者线程\n * 2) 先启动生产者线程\n * @author MarkShen\n */\npublic class T08_TransferQueue {\n\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\tLinkedTransferQueue<String> strs = new LinkedTransferQueue<>();\n\n\t\t// 先启动消费者线程\n\t\tnew Thread(() -> {\n\t\t\ttry {\n\t\t\t\tSystem.out.println(strs.take());\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}).start();\n\t\t\n\t\tstrs.transfer(\"aaa\");\n\t\t// strs.add(\"aaa\");\n\t\t// strs.offer(\"aaa\");\n\t\t// strs.put(\"aaa\");\n\n\t\t// 后启动消费者线程会发生阻塞\n//\t\tnew Thread(() -> {\n//\t\t\ttry {\n//\t\t\t\tSystem.out.println(strs.take());\n//\t\t\t} catch (InterruptedException e) {\n//\t\t\t\te.printStackTrace();\n//\t\t\t}\n//\t\t}).start();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent25/T09_SynchronousQueue.java",
    "content": "package com.mark.concurrent25;\n\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.SynchronousQueue;\n\n/**\n * @author MarkShen\n */\npublic class T09_SynchronousQueue {\n\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\t// 特殊的TransferQueue, 没有容量的Queue, 容量为0。\n\t\tBlockingQueue<String> strs = new SynchronousQueue<>();  // 没有容量的队列\n\t\t\n\t\tnew Thread(() -> {\n\t\t\ttry {\n\t\t\t\tSystem.out.println(strs.take());\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}).start();\n\t\t\n\t\t// strs.add(\"aaa\");\n\t\tstrs.put(\"aaa\");  // 阻塞等待消费者消费\n\t\tSystem.out.println(strs.size());\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T01_MyExecutor.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.concurrent.Executor;\n\n/**\n * Executor接口\n * @author MarkShen\n */\npublic class T01_MyExecutor implements Executor {\n\n\t@Override\n\tpublic void execute(Runnable command) {\n\t\t// new Thread(command).run();\n\t\tcommand.run();\n\t}\n\t\n\tpublic static void main(String[] args) {\n\t\tnew T01_MyExecutor().execute(() -> System.out.println(\"hello executor\"));\n\t}\n\t\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T02_ExecutorService.java",
    "content": "package com.mark.concurrent26;\n\n/**\n * ExecutorService 接口\n * @author MarkShen\n */\npublic class T02_ExecutorService {\n\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T03_Callable.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.FutureTask;\n\n/**\n * 注意与Runnable的区别\n * https://blog.csdn.net/qq_27258799/article/details/51451143\n * https://www.cnblogs.com/frinder6/p/5507082.html\n * @author MarkShen\n */\npublic class T03_Callable implements Callable<String> {\n\n\tprivate String acceptStr;\n\n\tpublic T03_Callable(String acceptStr) {\n\t\tthis.acceptStr = acceptStr;\n\t}\n\n\t@Override\n\tpublic String call() throws Exception {\n\t\t// 任务阻塞 1 秒\n\t\tThread.sleep(1000);\n\t\treturn this.acceptStr + \" append some chars and return it!\";\n\t\t// return null;\n\t}\n\n\tpublic static void main(String[] args) throws Exception {\n\t\tCallable<String> callable = new T03_Callable(\"my callable test!\");\n\t\tFutureTask<String> task = new FutureTask<>(callable);\n\t\tlong beginTime = System.currentTimeMillis();\n\t\t// 创建线程\n\t\tnew Thread(task).start();\n\t\t// 调用get()阻塞主线程，反之，线程不会阻塞\n\t\tString result = task.get();\n\t\tlong endTime = System.currentTimeMillis();\n\t\tSystem.out.println(\"hello : \" + result);\n\t\tSystem.out.println(\"cast : \" + (endTime - beginTime) / 1000 + \" second!\");\n\t}\n\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T04_Executors.java",
    "content": "package com.mark.concurrent26;\n\n/**\n * 类似设计的类\n * Arrays\n * Collections\n * Executors\n *\n * @author MarkShen\n */\npublic class T04_Executors {\n\tpublic static void main(String[] args) {\n\t\t\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T05_ThreadPool.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 固定线程个数的线程池\n * @author MarkShen\n */\npublic class T05_ThreadPool {\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\t// 固定的\n\t\tExecutorService service = Executors.newFixedThreadPool(9);\n\t\tfor (int i = 1; i <= 10; i ++) {\n\t\t\tservice.execute(()->{\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.MILLISECONDS.sleep(500);\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tSystem.out.println(Thread.currentThread().getName());\n\t\t\t});\n\t\t}\n\t\t\n\t\tSystem.out.println(service);\n\n\t\t// 关闭线程池\n\t\tservice.shutdown();\n\t\tSystem.out.println(service.isTerminated());\n\t\tSystem.out.println(service.isShutdown());\n\n\t\tSystem.out.println(service);\n\t\t\n\t\tTimeUnit.SECONDS.sleep(5);\n\t\tSystem.out.println(service.isTerminated());\n\t\tSystem.out.println(service.isShutdown());\n\n\t\tSystem.out.println(service);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T06_Future.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.FutureTask;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * @author MarkShen\n */\npublic class T06_Future {\n\tpublic static void main(String[] args) throws InterruptedException, ExecutionException {\n\t\t\n\t\tFutureTask<Integer> task = new FutureTask<>(() -> {\n\t\t\tTimeUnit.MILLISECONDS.sleep(500);\n\t\t\treturn 1000;\n\t\t}); // new Callable() {Integer call();}\n\t\t\n\t\tnew Thread(task).start();\n\t\tSystem.out.println(task.get());  // 阻塞\n\t\t\n\t\t// ***************************\n\t\tExecutorService service = Executors.newFixedThreadPool(5);\n\t\tFuture<Integer> f = service.submit(() -> {\n\t\t\tTimeUnit.MILLISECONDS.sleep(500);\n\t\t\treturn 1;\n\t\t});\n\t\t\n\t\tSystem.out.println(f.get());\n\t\t// System.out.println(f.isDone());\n\n\t\t// 结束线程\n\t\t// service.shutdown();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T07_ParallelComputing.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\n\n/**\n * 线程池：并行计算\n * @author MarkShen\n */\npublic class T07_ParallelComputing {\n\tpublic static void main(String[] args) throws InterruptedException, ExecutionException {\n\t\tlong start = System.currentTimeMillis();\n\t\tList<Integer> results = getPrime(1, 200000);\n\t\tlong end = System.currentTimeMillis();\n\t\tSystem.out.println(end - start);\n\n\t\t// 获取线程核心数\n\t\tfinal int cpuCoreNum = Runtime.getRuntime().availableProcessors();\n\n\t\tExecutorService service = Executors.newFixedThreadPool(cpuCoreNum + 1);\n\n\t\t// 为什么不平均分呢？ 跟素数计算有关系\n\t\tMyTask t1 = new MyTask(1, 80000);\n\t\tMyTask t2 = new MyTask(80001, 130000);\n\t\tMyTask t3 = new MyTask(130001, 170000);\n\t\tMyTask t4 = new MyTask(170001, 200000);\n\n\t\tFuture<List<Integer>> f1 = service.submit(t1);\n\t\tFuture<List<Integer>> f2 = service.submit(t2);\n\t\tFuture<List<Integer>> f3 = service.submit(t3);\n\t\tFuture<List<Integer>> f4 = service.submit(t4);\n\n\t\tstart = System.currentTimeMillis();\n\t\tf1.get();\n\t\tf2.get();\n\t\tf3.get();\n\t\tf4.get();\n\t\tend = System.currentTimeMillis();\n\t\tSystem.out.println(end - start);\n\n\t\t// 关闭线程池\n\t\tservice.shutdown();\n\t\tSystem.out.println(service.isShutdown());\n\t\tSystem.out.println(service.isTerminated());\n\t}\n\n\tstatic List<Integer> getPrime(int start, int end) {\n\t\tList<Integer> results = new ArrayList<Integer>();\n\t\tfor (int i = start; i <= end; i++) {\n\t\t\tif (isPrime(i))\n\t\t\t\tresults.add(i);\n\t\t}\n\t\treturn results;\n\t}\n\n\tstatic boolean isPrime(int num) {\n\t\tfor (int i = 2; i <= num; i++) {\n\t\t\tif (num % i == 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tstatic class MyTask implements Callable<List<Integer>> {\n\t\tint startPos, endPos;\n\n\t\tpublic MyTask(int startPos, int endPos) {\n\t\t\tthis.startPos = startPos;\n\t\t\tthis.endPos = endPos;\n\t\t}\n\n\t\t@Override\n\t\tpublic List<Integer> call() throws Exception {\n\t\t\tList<Integer> r = getPrime(startPos, endPos);\n\t\t\treturn r;\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T08_CachedThreadPool.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 刚开始一个线程也没有，来个任务起个线程。如果来个任务，线程池中有空闲的，直接使用空闲的线程。\n * 线程池中空闲线程空闲超过60s后，线程会自动消失。\n * @author MarkShen\n */\npublic class T08_CachedThreadPool {\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\tExecutorService service = Executors.newCachedThreadPool();\n\t\tSystem.out.println(service);\n\t\t\n\t\tfor (int i = 0; i < 2; i ++) {\n\t\t\tservice.execute(() -> {\n\t\t\t\ttry {\n\t\t\t\t\tTimeUnit.MILLISECONDS.sleep(500);\n\t\t\t\t} catch (InterruptedException e) {\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n\t\t\t\tSystem.out.println(Thread.currentThread().getName());\n\t\t\t});\n\t\t}\n\t\t\n\t\tSystem.out.println(service);\n\t\t\n\t\tTimeUnit.SECONDS.sleep(80);\n\t\t\n\t\tSystem.out.println(service);\n\n\t\tservice.shutdown();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T09_SingleThreadPool.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\n\n/**\n * 保证任务执行前后顺序 线程池中只有一个线程\n *\n * @author MarkShen\n */\npublic class T09_SingleThreadPool {\n\n    public static void main(String[] args) throws InterruptedException {\n        ExecutorService service = Executors.newSingleThreadExecutor();\n        for (int i = 0; i < 5; i++) {\n            final int j = i;\n            service.execute(() -> {\n                System.out.println(j + \" \" + Thread.currentThread().getName());\n            });\n        }\n        System.out.println(service.isTerminated());\n        service.shutdown();\n        System.out.println(service.isShutdown());\n        System.out.println(service.isTerminated());\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T10_ScheduleThreadPool.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.Random;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 定时任务线程池\n * @author MarkShen\n */\npublic class T10_ScheduleThreadPool {\n\tpublic static void main(String[] args) throws InterruptedException {\n\t\tScheduledExecutorService service = Executors.newScheduledThreadPool(4);\n\t\tservice.scheduleAtFixedRate(()->{\n\t\t\ttry {\n\t\t\t\tTimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000));\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tSystem.out.println(Thread.currentThread().getName());\n\t\t}, 0, 500, TimeUnit.MILLISECONDS);\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T11_WorkStealingPool.java",
    "content": "package com.mark.concurrent26;\n\nimport java.io.IOException;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 自己找活干的线程\n * @author MarkShen\n */\npublic class T11_WorkStealingPool {\n\tpublic static void main(String[] args) throws InterruptedException, IOException {\n\t\t// 根据CPU有几核启动多少个默认的线程\n\t\t// 主动找活儿干; 守护线程，虚拟机不退出，线程不退出。\n\t\tExecutorService service = Executors.newWorkStealingPool();\n\t\tSystem.out.println(Runtime.getRuntime().availableProcessors());  // 8核处理器\n\t\t\n\t\tservice.execute(new R(1000));\n\t\tservice.execute(new R(2000));\n\t\tservice.execute(new R(2000));\n\t\tservice.execute(new R(2000));\n\t\tservice.execute(new R(2000));\n\t\tservice.execute(new R(2000));\n\t\tservice.execute(new R(2000));\n\t\tservice.execute(new R(2000));\n\t\tservice.execute(new R(2000));\n\t\t\n\t\t// 由于WorkStealingPool是守护线程(Daemon Thread)， 主线程不阻塞，看不到输出\n\t\tSystem.in.read();\n\t}\n\t\n\tstatic class R implements Runnable {\n\n\t\tint time;\n\t\t\n\t\tpublic R(int time) {\n\t\t\tthis.time = time;\n\t\t}\n\n\t\t@Override\n\t\tpublic void run() {\n\t\t\ttry {\n\t\t\t\tTimeUnit.SECONDS.sleep(1);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\tSystem.out.println(Thread.currentThread().getName());\n\t\t}\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T12_ForkJoinPool.java",
    "content": "package com.mark.concurrent26;\n\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Random;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.concurrent.RecursiveAction;\nimport java.util.concurrent.RecursiveTask;\n\n/**\n * ForkJoin非常经典的算法\n *\n * https://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/index.html\n * 使用场景：大规模数据计算\n * 思路：多线程排序\n * @author MarkShen\n */\npublic class T12_ForkJoinPool {\n\tstatic int[] nums = new int[1000000];\n\tstatic final int MAX_NUM = 50000;\n\tstatic Random r = new Random();\n\t\n\tstatic {\n\t\tfor (int i = 0; i < nums.length; i ++) {\n\t\t\tnums[i] = r.nextInt(100);\n\t\t}\n\t\tSystem.out.println(Arrays.stream(nums).sum());\n\t}\n\t\n\tstatic class AddTask extends RecursiveAction {\n\n\t\tint start, end;\n\n\t\tpublic AddTask(int start, int end) {\n\t\t\tthis.start = start;\n\t\t\tthis.end = end;\n\t\t}\n\n\t\t@Override\n\t\tprotected void compute() {\n\t\t\tif (end - start <= MAX_NUM) {\n\t\t\t\tlong sum = 0L;\n\t\t\t\tfor(int i=start; i<end; i++) {\n\t\t\t\t\tsum += nums[i];\n\t\t\t\t}\n\t\t\t\tSystem.out.println(\"from:\" + start + \" to:\" + end + \"=\" + sum);\n\t\t\t} else {\n\t\t\t\tint middle = start + (end - start) / 2;\n\n\t\t\t\tAddTask subTask1 = new AddTask(start, middle);\n\t\t\t\tAddTask subTask2 = new AddTask(middle, end);\n\t\t\t\tsubTask1.fork();\n\t\t\t\tsubTask2.fork();\n\t\t\t}\n\t\t}\n\t}\n\t\n//\tstatic class AddTask extends RecursiveTask<Long> {\n//\n//\t\tint start, end;\n//\n//\t\tpublic AddTask(int start, int end) {\n//\t\t\tthis.start = start;\n//\t\t\tthis.end = end;\n//\t\t}\n//\n//\t\t@Override\n//\t\tprotected Long compute() {\n//\t\t\tif (end - start <= MAX_NUM) {\n//\t\t\t\tlong sum = 0L;\n//\t\t\t\tfor(int i=start; i<end; i++) {\n//\t\t\t\t\tsum += nums[i];\n//\t\t\t\t}\n//\t\t\t\treturn sum;\n//\t\t\t}\n//\n//\t\t\tint middle = start + (end - start) / 2;\n//\n//\t\t\tAddTask subTask1 = new AddTask(start, middle);\n//\t\t\tAddTask subTask2 = new AddTask(middle, end);\n//\t\t\tsubTask1.fork();\n//\t\t\tsubTask2.fork();\n//\n//\t\t\treturn subTask1.join() + subTask2.join();\n//\t\t}\n//\t}\n\t\n\tpublic static void main(String[] args) throws InterruptedException, IOException {\n\t\tForkJoinPool fjp = new ForkJoinPool();\n\t\tAddTask task = new AddTask(0, nums.length);\n\t\tfjp.execute(task);\n\n//\t\tlong result = task.join();\n//\t\tSystem.out.println(result);\n\n\t\tfjp.shutdown();\n\t\tSystem.in.read();\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T13_ThreadPoolExecutor.java",
    "content": "package com.mark.concurrent26;\n\nimport java.io.IOException;\nimport java.util.concurrent.ThreadPoolExecutor;\n\n/**\n * @author MarkShen\n * 自定义线程池\n * https://zhuanlan.zhihu.com/p/66992287\n */\npublic class T13_ThreadPoolExecutor {\n\tpublic static void main(String[] args) throws InterruptedException, IOException {\n\t\t// fixed, cache, single, schedule, forkjoin, workstealing\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T14_ParallelStreamAPI.java",
    "content": "package com.mark.concurrent26;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\n\n/**\n * 面试的时候往多线程上考虑考虑\n * @author MarkShen\n */\npublic class T14_ParallelStreamAPI {\n\tpublic static void main(String[] args) throws InterruptedException, IOException {\n\t\tList<Integer> nums = new ArrayList<Integer>();\n\t\tRandom r = new Random();\n\t\tfor (int i = 0; i < 10000; i ++)\n\t\t\tnums.add(1000000 + r.nextInt(1000000));\n\t\t\n\t\tlong start = System.currentTimeMillis();\n\t\tnums.forEach(v->isPrime(v));\n\t\tlong end = System.currentTimeMillis();\n\t\tSystem.out.println(end - start);\n\t\t\n\t\tstart = System.currentTimeMillis();\n\t\t// 默认使用多线程\n\t\tnums.parallelStream().forEach(T14_ParallelStreamAPI::isPrime);\n\t\tend = System.currentTimeMillis();\n\t\tSystem.out.println(end - start);\n\t}\n\n\tstatic boolean isPrime(int num) {\n\t\tfor (int i = 2; i <= num; i++) {\n\t\t\tif (num % i == 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/T15_SelfDefinitionThreadPool.java",
    "content": "package com.mark.concurrent26;\n\nimport java.util.concurrent.ArrayBlockingQueue;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.RejectedExecutionException;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * 自定义线程池\n *\n * @see https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html\n * @since 2021-11-07\n */\npublic class T15_SelfDefinitionThreadPool {\n\n    public static void main(String[] args) {\n        // Returns the number of processors available to the Java virtual machine.\n        int processorCount = Runtime.getRuntime().availableProcessors();\n        ThreadPoolExecutor threadPoolExecutor =\n            new ThreadPoolExecutor(processorCount, processorCount * 2, 1, TimeUnit.SECONDS, new ArrayBlockingQueue(10));\n        System.out.println(threadPoolExecutor);\n        int sum = 0;\n        try {\n            for (int i = 0; i < 10; i++) {\n                int tmpInt = i;\n                Future<Integer> result = threadPoolExecutor.submit(() -> sum(tmpInt, tmpInt + 10));\n                sum += result.get();\n            }\n        } catch (RejectedExecutionException e) {\n            System.out.println(\"task completed count=\" + threadPoolExecutor.getCompletedTaskCount());\n            threadPoolExecutor.shutdownNow();\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        } catch (ExecutionException e) {\n            e.printStackTrace();\n        }\n        System.out.println(sum);\n        System.out.println(\"Core Pool Size=\" + threadPoolExecutor.getCorePoolSize());\n        System.out.println(\"Maximum Pool Size=\" + threadPoolExecutor.getMaximumPoolSize());\n        System.out.println(\"Keepalive Time=\" + threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS));\n        threadPoolExecutor.shutdown();\n    }\n\n    static int sum(int start, int end) {\n        int sum = 0;\n        if (start >= end) {\n            return sum;\n        }\n        for (int i = start; i <= end; i++) {\n            sum += i;\n        }\n        return sum;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/mark/concurrent26/readme.txt",
    "content": "Executor：执行任务\nExecutorService\nCallable(exist return value) = Runnable(non-return value)\nExecutors: 工具类，类似工具类：Arrays, Collections\nThreadPool\nFuture:未来的结果\n\n如何设置线程数\n公式：最佳线程数目 = （（线程等待时间+线程CPU时间）/线程CPU时间 ）* CPU数目\n\nBrian Goetz建议，线程池大小与处理器的利用率之比可以使用下面的公式进行估算：\nNthreads = NCPU * UCPU * (1 + W/C)\n\n其中：\nNCPU是处理器的核的数目，可以通过Runtime.getRuntime().availableProcessors()得到\nUCPU是期望的CPU利用率（该值应该介于0和1之间）\nW/C是等待时间与计算时间的比率\n\n比如4核的处理器NCPU是4，你的程序计算一个方法需要5秒钟，整个程序运行也就需要5秒钟，那么W/C比率\n应该是100，\n\nNCPU利用率希望是100%那么也就是1，总体程序最佳的线程数应该是4*1*(1+100）=404个线程数，但实际操\n作中，设置404个线程明显不能带来性能的优势，这么多线程数只会增加上下文来回切换带来更严重的性能问\n题。\n\n重点配置：\n如果你的程序是计算密集型的并且没有IO操作，那么建议线程数设置为cpu核数+1，减少上下文切换。\n如果你的程序是IO密集型的（包括网络连接等待），那么可以按照 Nthreads = NCPU * UCPU * (1 + W/C)\n计算线程数.\n\n线程间通信：\n    共享内存\n    线程间发消息"
  },
  {
    "path": "src/main/java/com/mark/note/question.md",
    "content": "# 思考题\n- A线程正在执行一个对象中的同步方法，B线程是否可以同时执行同一个对象中的非同步方法？\n- 同上，B线程是否可以同时执行同一个对象中的另一个同步方法？\n- 线程抛出异常会释放吗？\n- volatile和synchronized区别\n- 写一个程序，证明AtomXXX类比synchronized更高效\n- AtomXXX类可以保证可见性吗？写个程序来证明。\n- 写一个程序证明AtomXXX类的多个方法并不构成原子性。\n- 写一个程序模拟死锁。\n- 写一个程序，在main线程中启动100个线程，100个线程完成后，主线程打印完成。使用join和CountDownLatch都可以完成。\n- 如何设计高效游戏服务器的架构。\n- synchronize和reentrantlock区别。\n\n  - 完成和synchronized一样的功能\n  \n  - 比synchronize灵活\n    \n    - tryLock\n    - tryLock可指定时间\n    - lockInterruptly()\n    - 指定锁为公平锁\n    \n  - 多查Java API\n"
  },
  {
    "path": "src/main/java/com/mmap/MemoryBufferTest.java",
    "content": "package com.mmap;\n\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.nio.ByteBuffer;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\n\n/**\n * https://medium.com/@trunghuynh/java-nio-using-memory-mapped-file-to-load-big-data-into-applications-5058b395cc9d\n *\n * @author MarkShen\n * @since 20231008\n */\npublic class MemoryBufferTest {\n    private static final String BTCUSDT_FILE_PATH = \"./BTCUSDT-1m.csv\";\n\n    public static void main(String[] args) throws Exception {\n        normalMemoryBuffer();\n        mappedBuffer();\n    }\n\n    private static void normalMemoryBuffer() throws IOException {\n        long startTime = System.currentTimeMillis();\n        RandomAccessFile file = new RandomAccessFile(BTCUSDT_FILE_PATH, \"rw\");\n        FileChannel channel = file.getChannel();\n        // Reading file into normal Memory buffer\n        ByteBuffer buffer = ByteBuffer.allocate((int)channel.size());\n        channel.read(buffer);\n        buffer.flip();\n\n        for (int i = 0; i < channel.size(); i++) {\n            System.out.print((char)buffer.get());\n        }\n        channel.close();\n        file.close();\n        System.out.println(\"Total read and print time: \" + (System.currentTimeMillis() - startTime));\n    }\n\n    private static void mappedBuffer() throws Exception {\n        long startTime = System.currentTimeMillis();\n        RandomAccessFile file = new RandomAccessFile(BTCUSDT_FILE_PATH, \"rw\");\n        FileChannel channel = file.getChannel();\n        // Read file into mapped buffer\n        MappedByteBuffer mbb = channel.map(FileChannel.MapMode.READ_WRITE, 0, channel.size());\n        System.out.println(\"Reading content and printing ... \");\n        for (int i = 0; i < channel.size(); i++) {\n            System.out.print((char)mbb.get());\n        }\n        channel.close();\n        file.close();\n        System.out.println(\"Total read and print time: \" + (System.currentTimeMillis() - startTime));\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/mmap/MmapWriteReadTest.java",
    "content": "package com.mmap;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.RandomAccessFile;\nimport java.nio.MappedByteBuffer;\nimport java.nio.channels.FileChannel;\n\n/**\n * https://howtodoinjava.com/java/nio/memory-mapped-files-mappedbytebuffer/\n *\n * @author MarkShen\n */\npublic class MmapWriteReadTest {\n    static int length = 0x8FFFFFF;\n\n    static String bigExcelFile = \"bigFile.xls\";\n\n    static String bigTextFile = \"test.txt\";\n\n    public static void main(String[] args) throws Exception {\n        write();\n\n    }\n\n    private static void write() throws IOException {\n        try (RandomAccessFile file = new RandomAccessFile(\"howtodoinjava.dat\", \"rw\")) {\n            MappedByteBuffer out = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);\n\n            for (int i = 0; i < length; i++) {\n                out.put((byte)'x');\n            }\n            System.out.println(\"Finished writing\");\n        }\n    }\n\n    private static void read() throws Exception {\n        try (RandomAccessFile file = new RandomAccessFile(new File(bigExcelFile), \"r\")) {\n            // Get file channel in read-only mode\n            FileChannel fileChannel = file.getChannel();\n\n            // Get direct byte buffer access using channel.map() operation\n            MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());\n\n            // the buffer now reads the file as if it were loaded in memory.\n            System.out.println(buffer.isLoaded()); // prints false\n            System.out.println(buffer.capacity()); // Get the size based on content size of file\n\n            // You can read the file from this buffer the way you like.\n            for (int i = 0; i < buffer.limit(); i++) {\n                System.out.print((char)buffer.get()); // Print the content of file\n            }\n        }\n    }\n\n    private static void writeIntoMemoryMappedFile() throws Exception {\n        // Create file object\n        File file = new File(bigTextFile);\n\n        // Delete the file; we will create a new file\n        file.delete();\n\n        try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, \"rw\")) {\n            // Get file channel in read-write mode\n            FileChannel fileChannel = randomAccessFile.getChannel();\n\n            // Get direct byte buffer access using channel.map() operation\n            MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 4096 * 8 * 8);\n\n            // Write the content using put methods\n            buffer.put(\"howtodoinjava.com\".getBytes());\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/program/CodeGenerator.java",
    "content": "package com.program;\n\nimport java.util.Random;\n\n/**\n * Code 生成器\n */\npublic class CodeGenerator {\n    private static String elements = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n\n    public static String generateCode(int codeLength) {\n        StringBuilder code = new StringBuilder();\n        Random random = new Random();\n        if (codeLength <= 0)\n            return \"\";\n        for (int i = 0; i < codeLength; i++) {\n            int index = random.nextInt(elements.length());\n            code.append(elements.charAt(index));\n        }\n        return code.toString();\n    }\n\n    /**\n     * https://dzone.com/articles/java-string-format-examples\n     *\n     * @param digits 位数\n     * @param val 值\n     * @return\n     */\n    public static String convert(int digits, int val) {\n        StringBuilder sb = new StringBuilder();\n        sb.append(\"%0\").append(digits).append(\"d\");\n        return String.format(sb.toString(), val);\n    }\n\n    public static void main(String[] args) {\n        System.out.println(generateCode(4));\n        System.out.println(convert(10, 1));\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/program/CollectionIterate.java",
    "content": "package com.program;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\n/**\n * @author MarkShen\n * @since 20210509\n */\npublic class CollectionIterate {\n\n    public static void main(String[] args) {\n        // 集合遍历方法之 List Set\n        List<String> strs = new ArrayList<>();\n        strs.add(\"a\");\n        strs.add(\"b\");\n        strs.add(\"c\");\n        strs.add(\"d\");\n        strs.add(\"f\");\n        strs.add(\"g\");\n\n        // 01\n        for (int i = 0; i < strs.size(); i++) {\n            System.out.println(strs.get(i));\n        }\n\n        // 02\n        for (String str : strs) {\n            System.out.println(str);\n        }\n\n        // 03\n        Iterator it = strs.iterator();\n        while (it.hasNext()) {\n            System.out.println(it.next());\n        }\n\n        // 04\n        strs.stream().forEach(s -> System.out.println(s));\n\n        // 集合遍历方法之 Map\n        Map<String, String> map = new HashMap<>();\n        map.put(\"a\", \"a\");\n        map.put(\"b\", \"b\");\n        map.put(\"c\", \"c\");\n        map.put(\"d\", \"d\");\n\n        // 01\n        for (Map.Entry<String, String> entry : map.entrySet()) {\n            String mapKey = entry.getKey();\n            String mapValue = entry.getValue();\n            System.out.println(mapKey + \":\" + mapValue);\n        }\n\n        // 02\n        Iterator<Entry<String, String>> entries = map.entrySet().iterator();\n        while (entries.hasNext()) {\n            Entry<String, String> entry = entries.next();\n            String key = entry.getKey();\n            String value = entry.getValue();\n            System.out.println(key + \":\" + value);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/main/java/com/program/ConstructTree.java",
    "content": "package com.program;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.stream.Collectors;\n\nimport com.alibaba.fastjson.JSON;\n\n/**\n * 树形结构遍历\n *\n * @author MarkShen\n * @Date 2021-02-25\n */\npublic class ConstructTree {\n\n    static class Menu {\n\n        private int id;\n        private String name;\n        private int pId;\n        private List<Menu> menu;\n\n        public Menu(int id, String name, int pId) {\n            this.id = id;\n            this.name = name;\n            this.pId = pId;\n        }\n\n        public int getId() {\n            return id;\n        }\n\n        public void setId(int id) {\n            this.id = id;\n        }\n\n        public String getName() {\n            return name;\n        }\n\n        public void setName(String name) {\n            this.name = name;\n        }\n\n        public int getpId() {\n            return pId;\n        }\n\n        public void setpId(int pId) {\n            this.pId = pId;\n        }\n\n        public List<Menu> getMenu() {\n            return menu;\n        }\n\n        public void setMenu(List<Menu> menu) {\n            this.menu = menu;\n        }\n\n        @Override\n        public String toString() {\n            return \"Menu{\" + \"id=\" + id + \", name='\" + name + '\\'' + \", pId=\" + pId + \", menu=\" + menu + '}';\n        }\n    }\n\n    public static void main(String[] args) {\n        List<Menu> menus = new ArrayList<>();\n        menus.add(new Menu(1, \"菜单管理\", 0));\n        menus.add(new Menu(2, \"系统管理\", 1));\n        menus.add(new Menu(3, \"用户管理\", 2));\n        menus.add(new Menu(4, \"机构管理\", 2));\n        menus.add(new Menu(5, \"权限管理\", 2));\n        menus.add(new Menu(6, \"角色管理\", 2));\n        menus.add(new Menu(7, \"货物管理\", 1));\n        menus.add(new Menu(8, \"仓库管理\", 1));\n\n        // 获取父节点\n        List<Menu> collect = menus.stream().filter(m -> m.getpId() == 0).map((m) -> {\n            m.setMenu(getChildrens(m, menus));\n            return m;\n        }).collect(Collectors.toList());\n        System.out.println(\"-------转json输出结果-------\");\n        System.out.println(JSON.toJSON(collect));\n    }\n\n    /**\n     * 递归查询子节点\n     *\n     * @param root\n     *            根节点\n     * @param all\n     *            所有节点\n     * @return 根节点信息\n     */\n    private static List<Menu> getChildrens(Menu root, List<Menu> all) {\n        List<Menu> children = all.stream().filter(m -> Objects.equals(m.getpId(), root.getId())).map((m) -> {\n            m.setMenu(getChildrens(m, all));\n            return m;\n        }).collect(Collectors.toList());\n        return children;\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/program/FizzBuzzDemo.java",
    "content": "package com.program;\n\n/**\n * 编写一个程序：把1-100的数字打印出来。不过，要把3的倍数打印成Bizz，把5的倍数打印成Buzz, 而这个数字 既是3的倍数又是5的倍数，就打成Bizz-Buzz。\n */\npublic class FizzBuzzDemo {\n    public static void main(String[] args) {\n        for (int i = 1; i <= 100; i++) {\n            if (i % 3 == 0 && i % 5 != 0) {\n                System.out.print(\" Bizz \");\n            } else if (i % 3 != 0 && i % 5 == 0) {\n                System.out.print(\" Buzz \");\n            } else if (i % 3 == 0 && i % 5 == 0) {\n                System.out.print(\" Bizz-Buzz \");\n            } else {\n                System.out.print(\" \" + i + \" \");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/program/ULIDTest.java",
    "content": "package com.program;\n\nimport java.util.concurrent.ThreadLocalRandom;\n\nimport io.azam.ulidj.ULID;\n\n/**\n * https://github.com/ulid/spec\n */\npublic class ULIDTest {\n\n    public static void main(String[] args) {\n        System.out.println(\"ULID....\");\n        String ulid1 = ULID.random();\n        String ulid2 = ULID.random(ThreadLocalRandom.current());\n        System.out.println(ulid1);\n        System.out.println(ulid2);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/program/WechatCircleLikeDisplay.java",
    "content": "package com.program;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 微信朋友圈点赞显示\n *\n * @author MarkShen\n * @since 20210506\n */\npublic class WechatCircleLikeDisplay {\n\n    private static final String COMMA = \",\";\n\n    public static void main(String[] args) {\n        // Bob, Mark, Mike\n        List<String> names = new ArrayList<>();\n        names.add(\"Bob\");\n        names.add(\"Mark\");\n        names.add(\"Mike\");\n\n        System.out.println(getWechatLikeStr(names));\n    }\n\n    private static String getWechatLikeStr(List<String> names) {\n        if (names == null || names.isEmpty()) {\n            return \"\";\n        }\n        StringBuilder sb = new StringBuilder();\n        for (int i = 0; i < names.size(); i++) {\n            if (i == 0) {\n                sb.append(names.get(i));\n            } else {\n                sb.append(COMMA).append(names.get(i));\n            }\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/snake/Direction.java",
    "content": "package com.snake;\n\n/**\n * 方向\n */\npublic enum Direction {\n    LEFT,\n    UP,\n    RIGHT,\n    DOWN\n}\n"
  },
  {
    "path": "src/main/java/com/snake/Egg.java",
    "content": "package com.snake;\n\nimport java.awt.*;\nimport java.util.Random;\n\n/**\n * 蛇食物位置\n */\npublic class Egg {\n    int row, col;\n\n    Random r = new Random();\n\n    public Egg(int row, int col) {\n        this.row = row;\n        this.col = col;\n    }\n\n    public void paint(Graphics g) {\n        int x = Yard.x + col * Yard.NODE_SIZE;\n        int y = Yard.y + row * Yard.NODE_SIZE;\n\n        Color c = g.getColor();\n        g.setColor(Color.RED);\n        g.fillOval(x, y, Yard.NODE_SIZE, Yard.NODE_SIZE);\n\n        // 恢复现场\n        g.setColor(c);\n    }\n\n    public void reAppear() {\n        this.row = r.nextInt(Yard.NODE_COUNT);\n        this.col = r.nextInt(Yard.NODE_COUNT);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/snake/Node.java",
    "content": "package com.snake;\n\nimport java.awt.*;\n\n/**\n * 双向链表\n */\npublic class Node {\n    int row, col;\n    Node pre, next;\n\n    public Node(int row, int col) {\n        this.row = row;\n        this.col = col;\n    }\n\n    public void paint(Graphics g) {\n        int x = Yard.x + col * Yard.NODE_SIZE;\n        int y = Yard.y + row * Yard.NODE_SIZE;\n\n        Color c = g.getColor();\n        g.setColor(Color.GREEN);\n        g.fillRect(x, y, Yard.NODE_SIZE, Yard.NODE_SIZE);\n\n        // 恢复现场\n        g.setColor(c);\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/snake/Snake.java",
    "content": "package com.snake;\n\nimport java.awt.*;\nimport java.awt.event.KeyEvent;\n\npublic class Snake {\n    Node head, tail;\n    Direction dir = Direction.LEFT;\n\n    public Snake() {\n        // initialize snake\n        head = new Node(20, 20);\n        tail = head;\n    }\n\n    /**\n     * 画出自己(面向对象的思维)\n     * @param g\n     */\n    public void paint(Graphics g) {\n        Node n = head;\n        while (n != null) {\n            n.paint(g);\n            n = n.next;\n        }\n\n        move();\n    }\n\n    private void move() {\n        addToHead();\n        deleteTail();\n        boundaryCheck();\n    }\n\n    private void boundaryCheck() {\n        if (head.row < 0) head.row = Yard.NODE_COUNT - 1;\n        if (head.col < 0) head.col = Yard.NODE_COUNT - 1;\n        if (head.row > Yard.NODE_COUNT - 1) head.row = 0;\n        if (head.col < Yard.NODE_COUNT - 1) head.col = 0;\n    }\n\n    private void addToHead() {\n        Node n = null;\n        switch (dir) {\n            case LEFT:\n                n = new Node(head.row, head.col - 1);\n                break;\n            case RIGHT:\n                n = new Node(head.row, head.col + 1);\n                break;\n            case UP:\n                n = new Node(head.row - 1, head.col);\n                break;\n            case DOWN:\n                n = new Node(head.row + 1, head.col);\n                break;\n        }\n\n        // add new snake head\n        n.next = head;\n        head.pre = n;\n        head = n;\n    }\n\n    private void deleteTail() {\n        if (tail == null)\n            return;\n        tail = tail.pre;\n        tail.next.pre = null; // 不加这句话，会有内存泄漏的风险\n        tail.next = null;\n    }\n\n    /**\n     * 判断用户按下那个键\n     * @param e\n     */\n    public void keyPressed(KeyEvent e) {\n        int key = e.getKeyCode();\n        switch (key) {\n            case KeyEvent.VK_LEFT:\n                dir = Direction.LEFT;\n                break;\n            case KeyEvent.VK_RIGHT:\n                dir = Direction.RIGHT;\n                break;\n            case KeyEvent.VK_UP:\n                dir = Direction.UP;\n                break;\n            case KeyEvent.VK_DOWN:\n                dir = Direction.DOWN;\n                break;\n        }\n    }\n\n    public void eat(Egg e) {\n        if (head.row == e.row && head.col == e.col) {\n            addToHead();\n            e.reAppear();\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/snake/Yard.java",
    "content": "package com.snake;\n\nimport java.awt.*;\nimport java.awt.event.KeyAdapter;\nimport java.awt.event.KeyEvent;\nimport java.awt.event.WindowAdapter;\nimport java.awt.event.WindowEvent;\n\npublic class Yard extends Frame {\n\n    public static final int NODE_SIZE = 15; // 格子大小\n    public static final int NODE_COUNT = 30; // 格子数量\n    public static final int AREA_WIDTH = NODE_SIZE * NODE_COUNT;\n\n    // 格子左上角点的坐标\n    public static int x = AREA_WIDTH / 2;\n    public static int y = AREA_WIDTH / 2;\n\n    private Egg e = new Egg(10, 10);\n    private Snake s = new Snake();\n\n    public Yard() {\n        this.setSize(2 * AREA_WIDTH, 2 * AREA_WIDTH);\n        this.setVisible(Boolean.TRUE);\n        // 添加关闭按钮事件\n        this.addWindowListener(new WindowAdapter() {\n            @Override\n            public void windowClosing(WindowEvent e) {\n                System.exit(0);\n            }\n        });\n\n        this.addKeyListener(new KeyAdapter() {\n            @Override\n            public void keyPressed(KeyEvent e) {\n                s.keyPressed(e);\n            }\n        });\n\n        // repaint\n        while (true) {\n            try {\n                Thread.sleep(100);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n            this.repaint();\n        }\n    }\n\n    /**\n     * 画出小蛇跑的区域\n     * @param g\n     */\n    @Override\n    public void paint(Graphics g) {\n        Color c = g.getColor();\n        g.setColor(Color.WHITE);\n        g.fillRect(0, 0, this.getWidth(), this.getHeight());\n        g.setColor(Color.BLACK);\n\n        for (int i = 0; i <= NODE_COUNT; i ++) {\n            // 画横线\n            g.drawLine(x, y + NODE_SIZE * i, x + AREA_WIDTH, y + NODE_SIZE * i);\n            // 画纵线\n            g.drawLine(x + NODE_SIZE * i, y, x + NODE_SIZE * i, y + AREA_WIDTH);\n        }\n\n        s.paint(g);\n        e.paint(g);\n        s.eat(e);\n        // 保持现场\n        g.setColor(c);\n    }\n\n    // 双缓冲\n    Image offScreenImage = null;\n    @Override\n    public void update(Graphics g) {\n        if (offScreenImage == null) {\n            offScreenImage = this.createImage(this.getWidth(), this.getHeight());\n        }\n        Graphics gOff = offScreenImage.getGraphics();\n        print(gOff);\n        g.drawImage(offScreenImage, 0, 0, null);\n    }\n\n    public static void main(String[] args) {\n        new Yard();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/AnimalBehavior.java",
    "content": "package com.thread;\n\n/**\n * @author MarkShen\n */\npublic interface AnimalBehavior {\n    default void eat() {\n        System.out.println(\"hello world\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/Cat.java",
    "content": "package com.thread;\n\n/**\n * @author MarkShen\n */\npublic class Cat implements AnimalBehavior {\n\n    @Override\n    public void eat() {\n        System.out.println(\"Cat eat...\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/CatMain.java",
    "content": "package com.thread;\n\n/**\n * @author MarkShen\n */\npublic class CatMain {\n    public static void main(String[] args) {\n        AnimalBehavior animalBehavior = new Cat();\n        animalBehavior.eat();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/MyRunnable.java",
    "content": "package com.thread;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * @author MarkShen\n */\npublic class MyRunnable implements Runnable {\n\n    @Override\n    public void run() {\n        Thread currentThread = Thread.currentThread();\n        System.out.println(currentThread.getName() + \"-------------进入\");\n\n        try {\n            TimeUnit.SECONDS.sleep(5);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        } finally {\n            System.out.println(currentThread.getName() + \"-------------离开\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/MyRunnableTest.java",
    "content": "package com.thread;\n\n/**\n * @author MarkShen\n */\npublic class MyRunnableTest {\n    public static void main(String[] args) {\n        MyRunnable runnable = new MyRunnable();\n        Thread thread1 = new Thread(runnable, \"线程1\");\n        Thread thread2 = new Thread(runnable, \"线程2\");\n        Thread thread3 = new Thread(runnable, \"线程3\");\n\n        thread1.start();\n        thread2.start();\n        thread3.start();\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/NotifySpecifiedThread.java",
    "content": "package com.thread;\n\nimport java.util.concurrent.locks.LockSupport;\n\n/**\n * 唤醒“指定”的某个线程\n *\n * 使用Java6引入了LockSupport这个类\n * @author MarkShen\n */\npublic class NotifySpecifiedThread {\n    public static void main(String[] args) throws Exception {\n        Thread t = new Thread(()->{\n            System.out.println(\"start\");\n            LockSupport.park(); // park可以让当前线程进入wait状态\n            System.out.println(\"continue\");\n        });\n        t.start();\n\n        Thread.sleep(1000);\n        LockSupport.unpark(t); // unpark可以解除指定线程的wait态，不需要拥有某个对象的特定锁\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/T.java",
    "content": "package com.thread;\n\npublic class T {\n    public static void main(String[] args) {\n        int a = 2;\n        switch (a) {\n            case 1:\n            case 2:\n                System.out.println(a);\n                break;\n            default:\n                System.out.println(a + 1);\n                break;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/com/thread/T01_TestJoin.java",
    "content": "package com.thread;\n\nimport java.util.concurrent.TimeUnit;\n\npublic class T01_TestJoin {\n    public static void main(String[] args) {\n        Thread t1 = new Thread(new MyThread(), \"t1\");\n        Thread t2 = new Thread(new MyThread(), \"t2\");\n\n        try {\n            // Waits for this thread to die.\n            t2.join(0);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n\n        t1.start();\n        t2.start();\n    }\n}\n\nclass MyThread implements Runnable {\n    @Override\n    public void run() {\n        // 线程通信\n        try {\n            TimeUnit.SECONDS.sleep(1);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n        System.out.println(Thread.currentThread().getName());\n    }\n}"
  },
  {
    "path": "src/test/java/com/java8/NewFeatureTest.java",
    "content": "package com.java8;\n\nimport junit.framework.TestCase;\nimport org.junit.Test;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.IntStream;\nimport java.util.stream.Stream;\n\n/**\n * Java 8 New feature test\n */\npublic class NewFeatureTest extends TestCase {\n\n    @Test\n    public void testLambda01() {\n        // () -> 3.14\n        // (value) -> (value % 2) == 0\n\n        // Lambda 表达式是匿名内部类的一种简化\n        MyVal myVal = () -> 3.14;\n        System.out.println(myVal.getVal());\n\n        ValidEvenNum validEvenNum = (value) -> (value % 2) == 0;\n        System.out.println(validEvenNum.isEven(10));\n    }\n\n    @Test\n    public void testLambda02() {\n        MyVal myVal = new MyVal() {\n            @Override\n            public double getVal() {\n                return 3.14;\n            }\n        };\n        System.out.println(myVal.getVal());\n    }\n\n    @Test\n    public void testLambda03() {\n        // Lambda 表达式和匿名内部类的应用，字符串的逆序输出 之\n        // IN: abcdefg OUT: gfedcba\n        display(\"abcdefg\", new MyFunctionalInterface() {\n            @Override\n            public String reverse(String s) {\n                StringBuilder sb = new StringBuilder();\n                char[] chars = s.toCharArray();\n                for (int i = chars.length - 1; i >= 0; i--) {\n                    sb.append(chars[i]);\n                }\n                return sb.toString();\n            }\n        });\n    }\n\n    @Test\n    public void testLambda04() {\n        // Lambda 表达式和匿名内部类的应用，字符串的逆序输出 之\n        // IN: abcdefg OUT: gfedcba\n        display(\"abcdefg\", (s) -> {\n            StringBuilder sb = new StringBuilder();\n            char[] chars = s.toCharArray();\n            for (int i = chars.length - 1; i >= 0; i--) {\n                sb.append(chars[i]);\n            }\n            return sb.toString();\n        });\n    }\n\n    public void display(String s, MyFunctionalInterface myFunctionalInterface) {\n        System.out.println(myFunctionalInterface.reverse(s));\n    }\n\n    interface MyFunctionalInterface {\n        String reverse(String s);\n    }\n\n    interface MyVal {\n        double getVal();\n    }\n\n    interface ValidEvenNum {\n        boolean isEven(int num);\n    }\n\n    // ===============================================================\n    // https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/\n    @Test\n    public void testLambda05() {\n        // 1. Individual values\n        Stream stream = Stream.of(\"a\", \"b\", \"c\");\n        stream.forEach(System.out::print);\n        System.out.println();\n        // 2. Arrays\n        String [] strArray = new String[] {\"a\", \"b\", \"c\"};\n        stream = Stream.of(strArray);\n        stream.forEach(System.out::print);\n        System.out.println();\n\n        stream = Arrays.stream(strArray);\n        stream.forEach(System.out::print);\n        System.out.println();\n\n        // 3. Collections\n        List<String> list = Arrays.asList(strArray);\n        stream = list.stream();\n        stream.forEach(System.out::print);\n    }\n\n    /**\n     * 数值流的构造\n     */\n    @Test\n    public void testLambda06() {\n        IntStream.of(new int[]{1, 2, 3}).forEach(System.out::print);\n        System.out.println();\n        IntStream.range(1, 3).forEach(System.out::print);\n        System.out.println();\n        IntStream.rangeClosed(1, 3).forEach(System.out::print);\n    }\n}\n"
  },
  {
    "path": "src/test/java/com/mark/concurrent01/TTest.java",
    "content": "package com.mark.concurrent01;\n\nimport junit.framework.TestCase;\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport java.time.Instant;\n\n/**\n * Unit test for simple App.\n */\npublic class TTest extends TestCase {\n  \n  @Before\n  public void setUp() throws Exception {}\n\n  @After\n  public void tearDown() throws Exception {}\n\n  @Test\n  public void testM() {\n    T t = new T();\n    new Thread(() -> t.m(), \"t1\").start();\n    new Thread(() -> t.m(), \"t2\").start();\n  }\n\n  @Test\n  public void testDate() {\n    // 46546544654.666\n    // way 01\n    Long currentTime = System.currentTimeMillis();\n    String currentTimeWay01 = currentTime / 1000L + \".\" + currentTime % 1000L;\n    System.out.println(currentTimeWay01);\n\n    // way 02\n    Instant instant = Instant.now();\n    System.out.println(instant);\n    System.out.println(instant.getEpochSecond()); // 秒数\n    System.out.println(instant.toEpochMilli()); // 毫秒\n    System.out.println(System.currentTimeMillis()); // 毫秒\n  }\n}\n"
  },
  {
    "path": "style/STYLE.md",
    "content": "## 统一代码风格\n如果要编辑本项目，一定要统一代码风格\n### 统一方案\n本工程代码遵守阿里巴巴[p3c](https://github.com/alibaba/p3c)规范，在代码开发前建议:\n* 安装阿里巴巴规约插件,用于提早发现不规范代码,具体安装方法参照:[p3c](https://github.com/alibaba/p3c)，里面有eclipse,idea的安装方法\n* 安装codeStyle插件,用于格式化代码的时候符合代码规范,安装方法见:[安装codeStyle插件](#codeStyleInstall)\n* checkStyle校验,这个不用安装,`mvn`在编译的时候自己会调用，写在`pom.xml`里，用`maven-pmd-plugin`调用`pmd-p3c`规范校验\n\n如果工作中遇到代码格式化问题，经常导致git冲突,也可以采用上面的方案\n### codeStyle插件安装<span id=\"codeStyleInstall\"/>\n这里注意下，不管eclipse或者idea，都需要导入eclipse文件夹下面的配置\n#### eclipse\n* 依次点击：`Window->Preferences->Java->Code Style->Formatter->Import`\n* 选择`style/eclipse/codestyle.xml`文件 确定\n* 默认在`Active profile`中选择新导入的`P3C-CodeStyle`，如未选择，请手动选择\n* 点击`Apply`完成配置\n![step](../img/style/eclipse/step.jpg)\n#### idea\n* 依次点击进入插件界面：`File->Settings->Plugins`，搜索 eclipse code formatter，如已有插件则不需安装，如没有，点击Search in repositories自动搜索线上插件。\n![step1](../img/style/idea/step1.png)\n* 导入`style/eclipse/codestyle.xml` 这里记住用的也是eclipse里面的 点击OK\n![step1](../img/style/idea/step2.png)\n* 依次点击进入插件界面：`File->Settings->Editor->Code Style->Java->Import Scheme->Intellij IDEA code style XML`，导入`style/idea/codestyle.xml` 这里用的是idea的配置文件\n![step1](../img/style/idea/step3.png)\n* 完成\n\n### 附\n#### windows系统,代码规范校验提示乱码\n这个是因为cmd默认gbk，cmd输入:`CHCP 65001` 在运行mvn 提示就是不会乱码了"
  },
  {
    "path": "style/codestyle/eclipse/codestyle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<profiles version=\"12\">\n    <profile kind=\"CodeFormatterProfile\" name=\"P3C-CodeStyle\" version=\"13\">\n        <!--可变参数的... Idea没有对应的配置项，强制insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_ellipsis\" value=\"insert\"/>\n        <!--枚举值之间 Idea没有对应的配置项，强制insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations\" value=\"insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=Java:SPACE_BEFORE_COMMA-->\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=Java:SPACE_BEFORE_COMMA\n        由于IDEA只有一个SPACE_BEFORE_COMMA选项，所以统一设置 insert_space_before_comma 为 do not insert\n        -->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments\"\n                 value=\"do not insert\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations\"\n                 value=\"do not insert\"/>\n        <!--insert_space_before_comma end-->\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=Java:SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments\" value=\"insert\"/>\n        <!--IDEA只有一个配置项SPACE_AFTER_COMMA，insert_space_after_comma*统一设置成insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation\" value=\"insert\"/>\n        <!--insert_space_after_comma end-->\n\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=Java:SPACE_BEFORE_COLON-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for\" value=\"insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=Java:SPACE_AFTER_COLON-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement\" value=\"insert\"/>\n\n        <!--IDEA不支持配置，默认do not insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case\" value=\"do not insert\"/>\n        <!--这个在Eclipse也没有找到配置的地方-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case\" value=\"do not insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_semicolon=Java:SPACE_BEFORE_SEMICOLON\n        程序导入的时候强制将SPACE_BEFORE_SEMICOLON设置为false\n        -->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for\" value=\"do not insert\"/>\n\n        <!--SPACE_AFTER_SEMICOLON=true-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources\" value=\"insert\"/>\n\n        <!--IDEA不支持配置,do not insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n\n        <!--IDEA不支持，使用默认-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator\" value=\"do not insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=Java:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_binary_operator\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_binary_operator\" value=\"insert\"/>\n\n        <!--IDEA不支持配置，使用如下值，两者对应-->\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters\"\n                 value=\"do not insert\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters\"\n                 value=\"insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference\"\n                value=\"do not insert\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments\"\n                 value=\"do not insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters\"\n                 value=\"do not insert\"/>\n\n        <!--Java:SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETER-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters\"\n                 value=\"do not insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=Java:SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENT-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments\"\n                 value=\"do not insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=Java:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block\" value=\"insert\"/>\n\n        <!--IDEA使用了对应的配置：Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES，但感觉不太好，IDEA默认不插入，Eclipse也使用不插入-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n\n        <!--use default insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return\"\n                 value=\"insert\"/>\n\n        <!--use default do not insert -->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch\" value=\"do not insert\"/>\n\n\n        <!--use default insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration\"\n                 value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw\"\n                 value=\"insert\"/>\n\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=Java:SPACE_BEFORE_SWITCH_LBRACE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch\" value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=Java:SPACE_BEFORE_CLASS_LBRACE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration\"\n                 value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=Java:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block\" value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=Java:SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer\"\n                 value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=Java:SPACE_BEFORE_METHOD_LBRACE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration\"\n                 value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=Java:SPACE_AFTER_QUEST-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional\" value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=Java:SPACE_BEFORE_QUEST-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional\" value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=Java:SPACE_BEFORE_ANOTATION_PARAMETER_LIST-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation\"\n                 value=\"do not insert\"/>\n\n        <!--use default do not insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_ellipsis\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast\" value=\"do not insert\"/>\n        <setting\n                id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration\"\n                value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference\"\n                 value=\"do not insert\"/>\n\n\n        <!--下面两个对应IDEA中的一个配置Java:SPACE_AROUND_ASSIGNMENT_OPERATORS，使用insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator\" value=\"insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=Java:SPACE_BEFORE_CATCH_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch\" value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=Java:SPACE_BEFORE_METHOD_CALL_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation\"\n                 value=\"do not insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=Java:SPACE_BEFORE_TRY_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try\" value=\"insert\"/>\n\n        <!--下面两个对应IDEA中的一个配置Java:SPACE_AROUND_UNARY_OPERATOR，使用do not insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_unary_operator\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_unary_operator\" value=\"do not insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=Java:SPACE_BEFORE_IF_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if\" value=\"insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=Java:SPACE_BEFORE_WHILE_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while\" value=\"insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=Java:SPACE_AFTER_TYPE_CAST-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast\" value=\"do not insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration\"\n                 value=\"do not insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=Java:SPACE_BEFORE_FOR_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for\" value=\"insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=Java:SPACE_BEFORE_SYNCHRONIZED_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized\" value=\"insert\"/>\n\n        <!--org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=Java:SPACE_BEFORE_SWITCH_PARENTHESES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch\" value=\"insert\"/>\n\n        <!--下面两个对应IDEA中的一个配置Java:SPACE_AROUND_LAMBDA_ARROW，使用insert-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow\" value=\"insert\"/>\n        <!--SPACE_WITHIN_EMPTY_ARRAY_INITIALIZER_BRACES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer\"\n                 value=\"do not insert\"/>\n\n        <!--Idea -> Wrapping And Braces -> Simple classes in one line -->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration\" value=\"do not insert\"/>\n        <!--Idea -> Wrapping And Braces -> Simple method in one line -->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body\" value=\"do not insert\"/>\n        <!--因为Idea不支持配置，所以设置为 Idea默认值-->\n\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant\"\n                 value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation\" value=\"do not insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_label\" value=\"insert\"/>\n        <!--Idea可以通过Wrap Always实现 TODO-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type\" value=\"insert\"/>\n        <!--Idea -> Wrapping And Braces -> Simple block in one line -> do not select -->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block\" value=\"insert\"/>\n\n        <!--Idea -> Wrapping And Braces -> try statement -> catch.... (Java:CATCH_ON_NEW_LINE)-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement\"\n                 value=\"do not insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing\" value=\"do not insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=Java:ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <!--#org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=Java:ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer\"\n                 value=\"do not insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=Java:ELSE_ON_NEW_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement\" value=\"do not insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=Java:WHILE_ON_NEW_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement\"\n                 value=\"do not insert\"/>\n        <!--org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=Java:FINALLY_ON_NEW_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement\"\n                 value=\"do not insert\"/>\n\n        <!--comment start-->\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.line_length\" value=\"120\"/>\n        <!--ENABLE_JAVADOC_FORMATTING-->\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_javadoc_comments\" value=\"true\"/>\n        <!--org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment\" value=\"false\"/>\n        <!--IDEA无对应设置，所以关闭对block comment的格式化 -->\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_block_comments\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries\" value=\"true\"/>\n\n        <!--org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=Java:KEEP_FIRST_COLUMN_COMMENT-->\n        <setting id=\"org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column\" value=\"false\"/>\n        <!--org.eclipse.jdt.core.formatter.use_on_off_tags=FORMATTER_TAGS_ENABLED-->\n        <setting id=\"org.eclipse.jdt.core.formatter.use_on_off_tags\" value=\"true\"/>\n        <!--org.eclipse.jdt.core.formatter.disabling_tag=FORMATTER_OFF_TAG-->\n        <setting id=\"org.eclipse.jdt.core.formatter.disabling_tag\" value=\"@formatter:off\"/>\n        <!--org.eclipse.jdt.core.formatter.enabling_tag=FORMATTER_ON_TAG-->\n        <setting id=\"org.eclipse.jdt.core.formatter.enabling_tag\" value=\"@formatter:on\"/>\n\n        <!--下面的没有IDEA对应项，在代码里面对IDEA中使用默认值即可,LINE_COMMENT_AT_FIRST_COLUMN BLOCK_COMMENT_AT_FIRST_COLUMN设置为false-->\n        <setting id=\"org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags\" value=\"insert\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.indent_root_tags\" value=\"true\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments\"\n                 value=\"false\"/>\n\n\n        <setting id=\"org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_line_comments\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_header\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries\" value=\"true\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_source_code\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.format_html\" value=\"true\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.join_lines_in_comments\" value=\"true\"/>\n        <!--和IDEA保持一致，注释换行-->\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.indent_parameter_description\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter\" value=\"insert\"/>\n\n\n        <!--comment end-->\n\n        <!--org.eclipse.jdt.core.formatter.blank_lines_after_imports=Java:BLANK_LINES_AFTER_IMPORTS-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_after_imports\" value=\"1\"/>\n        <!--org.eclipse.jdt.core.formatter.blank_lines_before_imports=Java:BLANK_LINES_BEFORE_IMPORTS-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_imports\" value=\"1\"/>\n        <!--org.eclipse.jdt.core.formatter.blank_lines_after_package=Java:BLANK_LINES_AFTER_PACKAGE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_after_package\" value=\"1\"/>\n        <!--org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=Java:BLANK_LINES_AROUND_CLASS-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations\" value=\"1\"/>\n        <!--org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=Java:BLANK_LINES_BEFORE_METHOD_BODY-->\n        <setting id=\"org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body\" value=\"0\"/>\n        <!--org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=Java:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration\" value=\"0\"/>\n        <!--org.eclipse.jdt.core.formatter.blank_lines_before_field=Java:BLANK_LINES_AROUND_FIELD-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_field\" value=\"0\"/>\n        <!--org.eclipse.jdt.core.formatter.blank_lines_before_method=Java:BLANK_LINES_AROUND_METHOD-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_method\" value=\"1\"/>\n        <!--org.eclipse.jdt.core.formatter.blank_lines_before_package=Java:BLANK_LINES_BEFORE_PACKAGE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_package\" value=\"0\"/>\n\n        <!--下面IDEA没有对应设置，使用对应值即可-->\n        <setting id=\"org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines\" value=\"2147483647\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_before_member_type\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.blank_lines_between_import_groups\" value=\"1\"/>\n\n        <!--org.eclipse.jdt.core.formatter.indentation.size=Java:IndentOptions:INDENT_SIZE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.indentation.size\" value=\"4\"/>\n        <!--org.eclipse.jdt.core.formatter.continuation_indentation=Java:IndentOptions:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.continuation_indentation\" value=\"1\"/>\n        <!--org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=Java:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header\" value=\"true\"/>\n        <!--org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=Java:IndentOptions:SMART_TABS-->\n        <setting id=\"org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations\" value=\"false\"/>\n        <!--org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=Java:INDENT_CASE_FROM_SWITCH-->\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch\" value=\"true\"/>\n        <!--KEEP_INDENTS_ON_EMPTY_LINES-->\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_empty_lines\" value=\"false\"/>\n        <!--org.eclipse.jdt.core.formatter.tabulation.size=Java:IndentOptions:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.tabulation.size\" value=\"4\"/>\n        <!--Java:IndentOptions:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.tabulation.char\" value=\"space\"/>\n\n\n        <!--下面IDEA没有对应设置，使用对应值即可-->\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_statements_compare_to_block\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header\"\n                 value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer\" value=\"1\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header\"\n                 value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_statements_compare_to_body\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header\"\n                 value=\"true\"/>\n\n\n        <!--Java:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_assignment\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_binary_expression\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_resources_in_try\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_conditional_expression\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer\" value=\"16\"/>\n\n        <!--下面没有对应的IDEA设置，Eclipse先使用对应值-->\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_enum_constants\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_type_parameters\" value=\"16\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration\" value=\"16\"/>\n\n\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_method_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_compact_if\" value=\"16\"/>\n\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_type_arguments\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression\"\n                 value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_multiple_fields\" value=\"16\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header\" value=\"16\"/>\n\n        <!--IDEA默认配置在同一行，Eclipse使用对应值即可-->\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration\"\n                 value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration\" value=\"common_lines\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration\" value=\"common_lines\"/>\n\n        <!--Java:BINARY_OPERATION_SIGN_ON_NEXT_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.wrap_before_binary_operator\" value=\"true\"/>\n\n        <!--ASSIGNMENT_WRAP 需要设置为 WRAP_AS_NEEDED  WRAP_AS_NEEDED . Add in jdt.core-3.12，it's not work in previous version -->\n        <setting id=\"org.eclipse.jdt.core.formatter.wrap_before_assignment_operator\" value=\"false\"/>\n\n        <!--IDEA无配置项，Eclipse使用对应值即可-->\n        <setting id=\"org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.wrap_before_conditional_operator\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested\" value=\"true\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line\" value=\"false\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line\" value=\"false\"/>\n\n        <!--org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=Java:KEEP_CONTROL_STATEMENT_IN_ONE_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line\" value=\"false\"/>\n        <!--org.eclipse.jdt.core.formatter.compact_else_if=Java:SPECIAL_ELSE_IF_TREATMENT-->\n        <setting id=\"org.eclipse.jdt.core.formatter.compact_else_if\" value=\"true\"/>\n        <!--Java:ALIGN_GROUP_FIELD_DECLARATIONS-->\n        <setting id=\"org.eclipse.jdt.core.formatter.align_type_members_on_columns\" value=\"false\"/>\n        <!--Java:<Programmatic>-->\n        <setting id=\"org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve\" value=\"1\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.join_wrapped_lines\" value=\"true\"/>\n\n        <!--统一为end_of_lint，IDEA默认一致-->\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_method_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_block\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_lambda_body\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_block_in_case\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration\"\n                 value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_switch\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_array_initializer\" value=\"end_of_line\"/>\n\n\n        <!--        <setting id=\"org.eclipse.jdt.core.compiler.source\" value=\"1.8\"/>\n                <setting id=\"org.eclipse.jdt.core.compiler.compliance\" value=\"1.8\"/>\n                <setting id=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.8\"/>\n                        <setting id=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"error\"/>\n                                <setting id=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"error\"/>\n                                        <setting id=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"enabled\"/>\n                -->\n        <!--Java:KEEP_SIMPLE_BLOCKS_IN_ONE_LINE-->\n        <setting id=\"org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line\" value=\"false\"/>\n\n        <!--Java:CLASS_BRACE_STYLE，统一使用end_of_line TODO-->\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_enum_constant\" value=\"end_of_line\"/>\n        <setting id=\"org.eclipse.jdt.core.formatter.brace_position_for_type_declaration\" value=\"end_of_line\"/>\n\n        <!--org.eclipse.jdt.core.formatter.lineSplit=RIGHT_MARGIN-->\n        <setting id=\"org.eclipse.jdt.core.formatter.lineSplit\" value=\"120\"/>\n    </profile>\n</profiles>\n"
  },
  {
    "path": "style/codestyle/idea/codestyle.xml",
    "content": "<code_scheme name=\"easyexcel\" version=\"173\">\n  <option name=\"AUTODETECT_INDENTS\" value=\"false\" />\n  <option name=\"CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"1024\" />\n  <option name=\"NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"1024\" />\n  <JavaCodeStyleSettings>\n    <option name=\"CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"1024\" />\n    <option name=\"NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND\" value=\"1024\" />\n    <option name=\"PACKAGES_TO_USE_IMPORT_ON_DEMAND\">\n      <value />\n    </option>\n    <option name=\"IMPORT_LAYOUT_TABLE\">\n      <value>\n        <package name=\"\" withSubpackages=\"true\" static=\"true\" />\n        <emptyLine />\n        <package name=\"java\" withSubpackages=\"true\" static=\"false\" />\n        <emptyLine />\n        <package name=\"javax\" withSubpackages=\"true\" static=\"false\" />\n        <emptyLine />\n        <package name=\"org\" withSubpackages=\"true\" static=\"false\" />\n        <emptyLine />\n        <package name=\"com\" withSubpackages=\"true\" static=\"false\" />\n        <emptyLine />\n        <package name=\"\" withSubpackages=\"true\" static=\"false\" />\n      </value>\n    </option>\n  </JavaCodeStyleSettings>\n</code_scheme>"
  },
  {
    "path": "test/test.txt",
    "content": "思考题\n\n1. A线程正在执行一个对象中的同步方法， B线程是否可以同时执行同一个对象中的非同步方法?\n2. 同上，B线程是否可以同时执行同一个对象中的另一个同步方法?\n3. 线程抛出异常会释放锁吗?\n4. volatile和synchronized区别? \n\t可见性， 原子性(synchronized), 可见性(volatile)\n5. 写一程序证明， AtomXXX类比synchronized更有效.\n6. AtomXXX类可以保证可见性吗?请写一个程序证明.\n7. 写一个程序证明AtomXXX类的多个方法并不构成原子性.\n8. 写一程序模拟死锁\n9. 写一个程序， 在main线程中启动100个线程，100个线程完成后，主线程打印完成， 使用join()和countDownLatch都可以完成。\n10. 一个高效的游戏服务器应该如何设计其架构。\n11. ReentrantLock与synchronized的区别\n12. 消息的可靠性和幂等\n\n共享资源读写的时候需要线程同步。\n线程同步方式：1)共享内存； 2)发消息"
  }
]