Repository: MarkShen1992/Mashibing_High_Concurrency Branch: master Commit: 1ba32218761e Files: 335 Total size: 58.9 MB Directory structure: gitextract__3rwbfmy/ ├── .editorconfig ├── .gitignore ├── .mvn/ │ ├── jvm.config │ └── wrapper/ │ └── maven-wrapper.properties ├── .travis.yml ├── README.md ├── concurrency.md ├── jvm/ │ └── jvm8 all parameters.txt ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src/ │ ├── main/ │ │ └── java/ │ │ └── com/ │ │ ├── annotation/ │ │ │ ├── README.md │ │ │ ├── jdk/ │ │ │ │ ├── Child.java │ │ │ │ ├── ParseAnnotation.java │ │ │ │ ├── Person.java │ │ │ │ └── Test.java │ │ │ ├── own/ │ │ │ │ └── Description.java │ │ │ └── project/ │ │ │ ├── Column.java │ │ │ ├── Department.java │ │ │ ├── Table.java │ │ │ ├── Test.java │ │ │ └── User.java │ │ ├── art/ │ │ │ └── concurrency/ │ │ │ ├── ch01/ │ │ │ │ ├── ConcurrencyTest.java │ │ │ │ └── DeadLockDemo.java │ │ │ ├── ch04/ │ │ │ │ ├── Daemon.java │ │ │ │ ├── Deprecated.java │ │ │ │ ├── Interrupted.java │ │ │ │ ├── MultiThread.java │ │ │ │ ├── Priority.java │ │ │ │ ├── Shutdown.java │ │ │ │ └── ThreadState.java │ │ │ ├── ch08/ │ │ │ │ ├── BankWaterService.java │ │ │ │ ├── CountDownLatchTest.java │ │ │ │ ├── CyclicBarrierTest.java │ │ │ │ ├── CyclicBarrierTest02.java │ │ │ │ ├── CyclicBarrierTest03.java │ │ │ │ ├── ExchangerTest.java │ │ │ │ └── SemaphoreTest.java │ │ │ └── utils/ │ │ │ └── SleepUtils.java │ │ ├── basic/ │ │ │ ├── alibaba/ │ │ │ │ ├── BigDecimalTest.java │ │ │ │ ├── CollectionTest.java │ │ │ │ ├── ConfusingName.java │ │ │ │ ├── DateTest.java │ │ │ │ ├── FloatPrimitiveTest.java │ │ │ │ ├── FloatWrapTest.java │ │ │ │ ├── IntegerCacheTest.java │ │ │ │ ├── LockTest.java │ │ │ │ ├── PrimitiveTypeArrayMaxSizeTest.java │ │ │ │ ├── SwitchTest.java │ │ │ │ └── package-info.java │ │ │ ├── chapter0100/ │ │ │ │ ├── Chapter0100Introduction.java │ │ │ │ ├── Chapter0101Identifier.java │ │ │ │ ├── Chapter0102JavaKeyWord.java │ │ │ │ ├── Chapter0103ConstantAndVariable.java │ │ │ │ ├── Chapter0104TestVar.java │ │ │ │ ├── Chapter0104TestVar2.java │ │ │ │ ├── Chapter0104VariableType.java │ │ │ │ ├── Chapter0105DataType.java │ │ │ │ ├── Chapter0106BasicDataTypeConvertPrinciple.java │ │ │ │ ├── Chapter0106TestConvert.java │ │ │ │ ├── Chapter0106TestConvert2.java │ │ │ │ ├── Chapter0107TestIF.java │ │ │ │ ├── Chapter0108For.java │ │ │ │ ├── Chapter0109TestWhile.java │ │ │ │ ├── Chapter0110TestBreakAndContinue.java │ │ │ │ ├── Chapter0111TestSwitch.java │ │ │ │ ├── Chapter0112TestMethod.java │ │ │ │ ├── Chapter0113TestMethod2.java │ │ │ │ ├── Chapter0114Fab.java │ │ │ │ ├── Test01.java │ │ │ │ └── Test02.java │ │ │ ├── chapter0200/ │ │ │ │ ├── Chapter0200Introduction.java │ │ │ │ ├── Chapter0201OO.java │ │ │ │ ├── Chapter0202ValueTransferAndReferenceTransfer.java │ │ │ │ ├── Chapter0203Point.java │ │ │ │ ├── Chapter0204MethodOverload.java │ │ │ │ ├── Chapter0205TestOverLoad.java │ │ │ │ ├── Chapter0206TestCircle.java │ │ │ │ ├── Chapter0207this.java │ │ │ │ ├── Chapter0208static.java │ │ │ │ ├── Chapter0209TestInherit.java │ │ │ │ ├── Chapter0210TestEquals.java │ │ │ │ ├── Chapter0211TestFinal.java │ │ │ │ ├── Chapter0212TestInterface.java │ │ │ │ ├── Chapter0213DoubleBraceInitializationModel.java │ │ │ │ ├── MessageFormatTest.java │ │ │ │ └── TestSuperSub.java │ │ │ ├── chapter0300/ │ │ │ │ ├── Chapter0300ExceptionIntroduction.java │ │ │ │ ├── Chapter0301TestEx.java │ │ │ │ ├── Chapter0302MethodException.java │ │ │ │ └── Chapter0303Junk.java │ │ │ ├── chapter0400/ │ │ │ │ ├── Chapter0401ArrayIntroduction.java │ │ │ │ ├── Chapter0402TestArgs.java │ │ │ │ ├── Chapter0403SortAlgorithm.java │ │ │ │ ├── Chapter0404TestDateSort.java │ │ │ │ ├── Chapter0405TestSearch.java │ │ │ │ ├── Chapter0406TestArrayCopy.java │ │ │ │ ├── Count3Quit.java │ │ │ │ └── Count3Quit2.java │ │ │ ├── chapter0500/ │ │ │ │ ├── Chapter0501CommonUseClass.java │ │ │ │ ├── Chapter0502TestString2.java │ │ │ │ ├── Chapter0503TestString3.java │ │ │ │ ├── Chapter0504TestString.java │ │ │ │ ├── Chapter0505StringBuffer.java │ │ │ │ ├── Chapter0506BasicTypeWrap.java │ │ │ │ ├── Chapter0507ArrayParser.java │ │ │ │ ├── Chapter0508TestMath.java │ │ │ │ ├── Chapter0509TestFile.java │ │ │ │ ├── Chapter0510FileList.java │ │ │ │ └── Chapter0511TestEnum.java │ │ │ ├── chapter0600/ │ │ │ │ ├── BasicContainer.java │ │ │ │ ├── BasicGeneric.java │ │ │ │ ├── CollectionsTest.java │ │ │ │ ├── DataStructureSelection.java │ │ │ │ ├── EnhancedFor.java │ │ │ │ ├── IteratorTest.java │ │ │ │ ├── SetTest.java │ │ │ │ ├── TestArgsWords.java │ │ │ │ ├── TestArgsWords2.java │ │ │ │ ├── TestMap.java │ │ │ │ └── TestMap2.java │ │ │ ├── chapter0700/ │ │ │ │ ├── FileCopy.java │ │ │ │ ├── HelloWorld.java │ │ │ │ ├── TestBufferStream1.java │ │ │ │ ├── TestBufferStream2.java │ │ │ │ ├── TestDataStream.java │ │ │ │ ├── TestFileInputStream.java │ │ │ │ ├── TestFileOutputStream.java │ │ │ │ ├── TestFileReader.java │ │ │ │ ├── TestFileWriter.java │ │ │ │ ├── TestFileWriter2.java │ │ │ │ ├── TestObjectIO.java │ │ │ │ ├── TestPrintStream1.java │ │ │ │ ├── TestPrintStream2.java │ │ │ │ ├── TestPrintStream3.java │ │ │ │ ├── TestTransForm1.java │ │ │ │ ├── TestTransForm2.java │ │ │ │ └── TreeDir.java │ │ │ ├── chapter0800/ │ │ │ │ ├── 111.txt │ │ │ │ ├── ProducerConsumer.java │ │ │ │ ├── ProducerConsumer2.java │ │ │ │ ├── RecursiveFile.java │ │ │ │ ├── T.java │ │ │ │ ├── TT.java │ │ │ │ ├── Test.java │ │ │ │ ├── TestDeadLock.java │ │ │ │ ├── TestInterrupt.java │ │ │ │ ├── TestJoin.java │ │ │ │ ├── TestPriority.java │ │ │ │ ├── TestSync.java │ │ │ │ ├── TestThread1.java │ │ │ │ ├── TestThread2.java │ │ │ │ ├── TestThread3.java │ │ │ │ ├── TestThread4.java │ │ │ │ ├── TestThread5.java │ │ │ │ ├── TestThread6.java │ │ │ │ └── TestYield.java │ │ │ ├── chapter0900/ │ │ │ │ ├── Chapter0901TestUDPClient.java │ │ │ │ ├── Chapter0901TestUDPServer.java │ │ │ │ ├── Chat/ │ │ │ │ │ ├── Chat03/ │ │ │ │ │ │ ├── ChatClient.java │ │ │ │ │ │ └── ChatServer.java │ │ │ │ │ ├── Chat05/ │ │ │ │ │ │ ├── ChatClient.java │ │ │ │ │ │ └── ChatServer.java │ │ │ │ │ ├── Chat07/ │ │ │ │ │ │ ├── ChatClient.java │ │ │ │ │ │ └── ChatServer.java │ │ │ │ │ └── Chat10/ │ │ │ │ │ ├── ChatClient.java │ │ │ │ │ └── ChatServer.java │ │ │ │ ├── TCPClient.java │ │ │ │ ├── TCPServer.java │ │ │ │ ├── TalkClient.java │ │ │ │ ├── TalkServer.java │ │ │ │ ├── TestClient.java │ │ │ │ ├── TestServer.java │ │ │ │ ├── TestSockClient.java │ │ │ │ ├── TestSockServer.java │ │ │ │ ├── TestUDPClient.java │ │ │ │ ├── TestUDPServer.java │ │ │ │ └── zerocopy/ │ │ │ │ ├── traditonal/ │ │ │ │ │ ├── TraditionalClient.java │ │ │ │ │ └── TraditionalServer.java │ │ │ │ └── transfer/ │ │ │ │ ├── TransferToClient.java │ │ │ │ └── TransferToServer.java │ │ │ ├── chapter1000/ │ │ │ │ ├── AWTDrawing.java │ │ │ │ ├── AWTDrawing2.java │ │ │ │ ├── CenterPanel.java │ │ │ │ ├── MyMouseAdapter.java │ │ │ │ ├── MyMouseAdapterGeneric.java │ │ │ │ ├── NestedContainer.java │ │ │ │ ├── TFActionEvent.java │ │ │ │ ├── TFMath.java │ │ │ │ ├── TFMathTest.java │ │ │ │ ├── TFMathTest2.java │ │ │ │ ├── TFPassword.java │ │ │ │ ├── TenButtons.java │ │ │ │ ├── Test.java │ │ │ │ ├── TestActionEvent.java │ │ │ │ ├── TestActionEvent2.java │ │ │ │ ├── TestAnonymous.java │ │ │ │ ├── TestAnonymous2.java │ │ │ │ ├── TestBorderLayout.java │ │ │ │ ├── TestFlowLayout.java │ │ │ │ ├── TestFlowLayout2.java │ │ │ │ ├── TestFrame.java │ │ │ │ ├── TestFrameWithPanel.java │ │ │ │ ├── TestGridLayout.java │ │ │ │ ├── TestInner.java │ │ │ │ ├── TestKey.java │ │ │ │ ├── TestMouseMotion.java │ │ │ │ ├── TestMouseMotionGeneric.java │ │ │ │ ├── TestMultiFrame.java │ │ │ │ ├── TestMultiPanel.java │ │ │ │ ├── TestPaint.java │ │ │ │ ├── TestPanel.java │ │ │ │ └── TestWindowClose.java │ │ │ ├── chapter1100/ │ │ │ │ └── TestReflect.java │ │ │ └── chapter1200/ │ │ │ ├── QQClient.java │ │ │ └── QQServer.java │ │ ├── geo/ │ │ │ ├── GeoLite2-City.mmdb │ │ │ └── GeoTest.java │ │ ├── java10/ │ │ │ └── NewFeatures.java │ │ ├── java11/ │ │ │ └── NewFeatures.java │ │ ├── java12/ │ │ │ └── NewFeatures.java │ │ ├── java13/ │ │ │ └── NewFeatures.java │ │ ├── java14/ │ │ │ └── Java14NewFeatures.java │ │ ├── java15/ │ │ │ └── NewFeatures.java │ │ ├── java16/ │ │ │ └── Java16NewFeatures.java │ │ ├── java17/ │ │ │ └── Java17NewFeatures.java │ │ ├── java18/ │ │ │ └── Java18Features.java │ │ ├── java19/ │ │ │ └── Java19Features.java │ │ ├── java5/ │ │ │ └── NewFeatures.java │ │ ├── java6/ │ │ │ └── NewFeatures.java │ │ ├── java7/ │ │ │ └── NewFeatures.java │ │ ├── java8/ │ │ │ ├── Demo0100_LambdaRunnable.java │ │ │ ├── Demo0200_LambdaIterator.java │ │ │ ├── Demo0300_LambdaPredicate.java │ │ │ ├── Demo0400_LambdaMapReduce.java │ │ │ ├── Demo0500_LambdaSimpleDemo.java │ │ │ ├── Demo0600_Stream.java │ │ │ ├── Demo0700_Stream.java │ │ │ ├── Demo0800_Stream.java │ │ │ ├── NewFeatures.java │ │ │ └── Person.java │ │ ├── java9/ │ │ │ └── NewFeatures.java │ │ ├── jvm/ │ │ │ └── OutOfMemoryException.java │ │ ├── mark/ │ │ │ ├── concurrent01/ │ │ │ │ └── T.java │ │ │ ├── concurrent02/ │ │ │ │ ├── T.java │ │ │ │ └── T2.java │ │ │ ├── concurrent03/ │ │ │ │ └── T.java │ │ │ ├── concurrent04/ │ │ │ │ └── T.java │ │ │ ├── concurrent05/ │ │ │ │ └── T.java │ │ │ ├── concurrent06/ │ │ │ │ ├── T.java │ │ │ │ └── T2.java │ │ │ ├── concurrent07/ │ │ │ │ └── T.java │ │ │ ├── concurrent08/ │ │ │ │ └── Account.java │ │ │ ├── concurrent09/ │ │ │ │ └── T.java │ │ │ ├── concurrent10/ │ │ │ │ └── T.java │ │ │ ├── concurrent11/ │ │ │ │ └── T.java │ │ │ ├── concurrent12/ │ │ │ │ └── T.java │ │ │ ├── concurrent13/ │ │ │ │ └── T.java │ │ │ ├── concurrent14/ │ │ │ │ └── T.java │ │ │ ├── concurrent15/ │ │ │ │ └── T.java │ │ │ ├── concurrent16/ │ │ │ │ └── T.java │ │ │ ├── concurrent17/ │ │ │ │ └── T.java │ │ │ ├── concurrent18/ │ │ │ │ └── T.java │ │ │ ├── concurrent19/ │ │ │ │ ├── MyContainer1.java │ │ │ │ ├── MyContainer2.java │ │ │ │ ├── MyContainer3.java │ │ │ │ ├── MyContainer4.java │ │ │ │ └── MyContainer5.java │ │ │ ├── concurrent20/ │ │ │ │ ├── ReentrantLock1.java │ │ │ │ ├── ReentrantLock2.java │ │ │ │ ├── ReentrantLock3.java │ │ │ │ ├── ReentrantLock4.java │ │ │ │ └── ReentrantLock5.java │ │ │ ├── concurrent21/ │ │ │ │ ├── MyContainer1.java │ │ │ │ └── MyContainer2.java │ │ │ ├── concurrent22/ │ │ │ │ ├── ThreadLocal1.java │ │ │ │ └── ThreadLocal2.java │ │ │ ├── concurrent23/ │ │ │ │ └── Singleton.java │ │ │ ├── concurrent24/ │ │ │ │ ├── TicketSeller1.java │ │ │ │ ├── TicketSeller2.java │ │ │ │ ├── TicketSeller3.java │ │ │ │ └── TicketSeller4.java │ │ │ ├── concurrent25/ │ │ │ │ ├── T01_ConcurrentMap.java │ │ │ │ ├── T02_CopyOnWriteList.java │ │ │ │ ├── T03_SynchronizedList.java │ │ │ │ ├── T04_ConcurrentQueue.java │ │ │ │ ├── T05_LinkedBlockingQueue.java │ │ │ │ ├── T06_ArrayBlockingQueue.java │ │ │ │ ├── T07_DelayQueue.java │ │ │ │ ├── T08_TransferQueue.java │ │ │ │ └── T09_SynchronousQueue.java │ │ │ ├── concurrent26/ │ │ │ │ ├── T01_MyExecutor.java │ │ │ │ ├── T02_ExecutorService.java │ │ │ │ ├── T03_Callable.java │ │ │ │ ├── T04_Executors.java │ │ │ │ ├── T05_ThreadPool.java │ │ │ │ ├── T06_Future.java │ │ │ │ ├── T07_ParallelComputing.java │ │ │ │ ├── T08_CachedThreadPool.java │ │ │ │ ├── T09_SingleThreadPool.java │ │ │ │ ├── T10_ScheduleThreadPool.java │ │ │ │ ├── T11_WorkStealingPool.java │ │ │ │ ├── T12_ForkJoinPool.java │ │ │ │ ├── T13_ThreadPoolExecutor.java │ │ │ │ ├── T14_ParallelStreamAPI.java │ │ │ │ ├── T15_SelfDefinitionThreadPool.java │ │ │ │ └── readme.txt │ │ │ └── note/ │ │ │ └── question.md │ │ ├── mmap/ │ │ │ ├── MemoryBufferTest.java │ │ │ └── MmapWriteReadTest.java │ │ ├── program/ │ │ │ ├── CodeGenerator.java │ │ │ ├── CollectionIterate.java │ │ │ ├── ConstructTree.java │ │ │ ├── FizzBuzzDemo.java │ │ │ ├── ULIDTest.java │ │ │ └── WechatCircleLikeDisplay.java │ │ ├── snake/ │ │ │ ├── Direction.java │ │ │ ├── Egg.java │ │ │ ├── Node.java │ │ │ ├── Snake.java │ │ │ └── Yard.java │ │ └── thread/ │ │ ├── AnimalBehavior.java │ │ ├── Cat.java │ │ ├── CatMain.java │ │ ├── MyRunnable.java │ │ ├── MyRunnableTest.java │ │ ├── NotifySpecifiedThread.java │ │ ├── T.java │ │ └── T01_TestJoin.java │ └── test/ │ └── java/ │ └── com/ │ ├── java8/ │ │ └── NewFeatureTest.java │ └── mark/ │ └── concurrent01/ │ └── TTest.java ├── style/ │ ├── STYLE.md │ └── codestyle/ │ ├── eclipse/ │ │ └── codestyle.xml │ └── idea/ │ └── codestyle.xml └── test/ └── test.txt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*.{groovy, java, kt, xml}] #缩进风格:空格 indent_style = space #缩进大小 indent_size = 4 #换行符lf end_of_line = lf #字符集utf-8 charset = utf-8 #是否删除行尾的空格 trim_trailing_whitespace = true #是否在文件的最后插入一个空行 insert_final_newline = true ================================================ FILE: .gitignore ================================================ # Compiled class file *.class # Log file *.log # BlueJ files *.ctxt # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar *.war *.nar *.ear *.zip *.tar.gz *.rar # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* # Eclipse project files .classpath .project .settings .settings/ target/ # IDEA metadata and output dirs *.iml *.ipr *.iws .idea/ # gitbook _book tmp .springBeans ================================================ FILE: .mvn/jvm.config ================================================ -Xmx1536m ================================================ FILE: .mvn/wrapper/maven-wrapper.properties ================================================ distributionUrl=https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar ================================================ FILE: .travis.yml ================================================ language: java jdk: openjdk8 cache: directories: - $HOME/.m2 before_install: - chmod +x mvnw install: - ./mvnw install -B -V -Dmaven.test.skip=true ================================================ FILE: README.md ================================================ ### 小统计: ![Stargazers over time](https://starchart.cc/MarkShen1992/Mashibing_High_Concurrency.svg) > **Don't count the days, make each day count.** ### 代码目录 - Chapter00_初识Java - Hello World - 初步认识 - 代码风格 - [谷歌代码风格](https://google.github.io/styleguide) - [阿里代码风格](https://github.com/alibaba/p3c) - [Chapter01_Java语言基础](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0100) - **关键字**:if, else, switch, for, while, do while, break, continue, void - 变量作用域:**出了这个大括号就再也没有人认识这个变量了。** - 基本数据类型:**四类八种** - 整数类型:byte(1 byte), short(2 bytes), int(4 bytes), long(8 bytes) - 浮点类型:float(4 bytes), double(8 bytes) - 字符类型:char(2 bytes) - 布尔类型:boolean > 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. > > ​ -- [*JVMS8*](https://github.com/MarkShen1992/bookstore/tree/master/java/Java%20Virtual%20Machine/jvm8) ```java boolean flag = false; ``` >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. > >​ -- [*JVMS8*](https://github.com/MarkShen1992/bookstore/tree/master/java/Java%20Virtual%20Machine/jvm8) ```java boolean[] flags = {false, true, false, true, true}; ``` - 形参,实参,返回值,返回值类型 - 递归调用 - [**Chapter02_面向对象编程**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0200) - **内存分析贯穿始终,画图分析** - 对象与类的概念 - **面向对象设计思想** - 第一步:考虑问题域中有哪些类,哪些对象 - 第二步:这些个类,这些个对象有哪些个属性 - 第三步:考虑类与类之间的关系,定他们之间的方法 - class - new - 引用的概念 - 构造方法的概念 - 方法重载(编译时多态) - 参数个数 - 参数类型 - 参数顺序 - this - super - static - package & import - private default protected public - extends - override - final - Object - equals - toString - upcasting downcasting - polymorphism / dynamic binding / late - 有继承关系存在 - 存在方法重写 @Override - 父类引用指向子类对象 - abstract class - interface - implements - [Chapter03_Java异常处理机制](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0300) - 一个图 ![Exception](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/materials/Exception.png) - 五个关键字 - try, catch, finally, throw, throws - 异常捕获原则 - 先逮小的,再逮大的 - 异常和重写的关系: **重写方法需要抛出与原方法所抛出异常类型一致的异常 或者 不抛出异常** - [Chapter04_数组](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0400) - 数组的内存布局 - 常见算法 - [Chapter05_Java常用类](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0500) - 正则表达式 - 基础类型包装类 - Math - File - 递归 - 枚举类型 - [**Chapter06_容器类**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0600) - 一个图 ![Collection Framework](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/materials/CollectionFramework.png) - 一个类 - Collections - 三个知识点 - For - Generic - Auto-boxing / unboxing - 六个接口 - Collection - Set - List - Map - Iterator - Comparable - [**Chapter07_IO流技术**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0700) ![Java IO](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/materials/Java%20IO.jpg) - InputStream / OutputStream - Reader / Writer - FileInputStream / FileOutputStream - FileReader / FileWriter - BufferedInputStream / BufferedOutputStream - BufferedReader / BufferedWriter - ByteArrayInputStream / ByteArrayOutputStream - InputStreamReader / OutputStreamWriter - DataInputStream / DataOutputStream - PrintStream / PrintWriter - ObjectInputStream / ObjectOutputStream - 分类 - 方向:输入流,输出流 - 数据处理单位:字节流,字符流 - 功能:节点流,处理流 - [**Chapter08_多线程**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0800) - 线程/进程/协程 - 创建启动线程的方式 - sleep, join, yield, synchronized, wait, notify, notifyAll - [Chapter09_网络编程](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter0900) - 网络协议分层思想 - IP概念 - TCP / UDP概念 - TCP / UDP程序的写法 - 知识点融会贯通,+ io 应用 - [Chapter10_GUI](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter1000) - 事件模型,**观察者模式** - [设计模式的代码](https://github.com/MarkShen1992/DesignPattern), 使用MyEclipse打开更好,有图可以看 - [Chapter11_反射](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/basic/chapter1100) - [**Chapter12_并发包类讲解代码**](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/mark) - [第一讲 concurrent1-19](https://v.qq.com/x/page/x052229kmeq.html) - [第二讲 concurrent20-22](https://v.qq.com/x/page/f05224z6ul9.html) - [第三讲 concurrent23-25](https://v.qq.com/x/page/z0522fzc1q3.html) - [第四讲 concurrent26](https://v.qq.com/x/page/u0522rgqjyk.html) - 高并发编程三大块: - 同步器(synchronizer) - 同步容器 - 线程池 - Executor - Future - Callable - 框架 - [disruptor](https://github.com/LMAX-Exchange/disruptor) - [netty](https://netty.io/) - [Chapter13_利用反射做的小项目](https://github.com/MarkShen1992/Mashibing_High_Concurrency/tree/master/src/main/java/com/annotation) - 常用工具代码 - [树形结构遍历](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/src/main/java/com/program/ConstructTree.java) - [Code生成](https://github.com/MarkShen1992/Mashibing_High_Concurrency/blob/master/src/main/java/com/program/CodeGenerator.java) 如果你喜欢这个项目,请我喝杯咖啡吧。 drawing ================================================ FILE: concurrency.md ================================================ # 马士兵高并发编程视频教程源码。 ### 线程池类图 ![线程池类图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) ### 计算机体系结构 ![冯诺依曼](http://images2015.cnblogs.com/blog/407610/201510/407610-20151014095555022-881385577.jpg) ![冯诺依曼体系结构](https://yun.kejimofang.com/intericon/20190427nuoyi.jpg) ![冯诺依曼](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61604.png) ![CPU&RAM](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61606.png) ![CPU&RAM](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61610.png) ![CPU&RAM](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61612.png) ![computer](https://www.oreilly.com/library/view/designing-embedded-hardware/0596007558/httpatomoreillycomsourceoreillyimages61622.png) 计算机硬件知识 ================================================ FILE: jvm/jvm8 all parameters.txt ================================================ java -XX:+PrintFlagsFinal -version java version "1.8.0_112" Java(TM) SE Runtime Environment (build 1.8.0_112-b15) Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode) JVM 参数学习网站 https://segmentfault.com/a/1190000040803727 https://opts.console.heapdump.cn/ [Global flags] uintx AdaptiveSizeDecrementScaleFactor = 4 {product} uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product} uintx AdaptiveSizePausePolicy = 0 {product} uintx AdaptiveSizePolicyCollectionCostMargin = 50 {product} uintx AdaptiveSizePolicyInitializingSteps = 20 {product} uintx AdaptiveSizePolicyOutputInterval = 0 {product} uintx AdaptiveSizePolicyWeight = 10 {product} uintx AdaptiveSizeThroughPutPolicy = 0 {product} uintx AdaptiveTimeWeight = 25 {product} bool AdjustConcurrency = false {product} bool AggressiveOpts = false {product} intx AliasLevel = 3 {C2 product} bool AlignVector = true {C2 product} intx AllocateInstancePrefetchLines = 1 {product} intx AllocatePrefetchDistance = 256 {product} intx AllocatePrefetchInstr = 0 {product} intx AllocatePrefetchLines = 3 {product} intx AllocatePrefetchStepSize = 64 {product} intx AllocatePrefetchStyle = 1 {product} bool AllowJNIEnvProxy = false {product} bool AllowNonVirtualCalls = false {product} bool AllowParallelDefineClass = false {product} bool AllowUserSignalHandlers = false {product} bool AlwaysActAsServerClassMachine = false {product} bool AlwaysCompileLoopMethods = false {product} bool AlwaysLockClassLoader = false {product} bool AlwaysPreTouch = false {product} bool AlwaysRestoreFPU = false {product} bool AlwaysTenure = false {product} bool AssertOnSuspendWaitFailure = false {product} bool AssumeMP = false {product} intx AutoBoxCacheMax = 128 {C2 product} uintx AutoGCSelectPauseMillis = 5000 {product} intx BCEATraceLevel = 0 {product} intx BackEdgeThreshold = 100000 {pd product} bool BackgroundCompilation = true {pd product} uintx BaseFootPrintEstimate = 268435456 {product} intx BiasedLockingBulkRebiasThreshold = 20 {product} intx BiasedLockingBulkRevokeThreshold = 40 {product} intx BiasedLockingDecayTime = 25000 {product} intx BiasedLockingStartupDelay = 4000 {product} bool BindGCTaskThreadsToCPUs = false {product} bool BlockLayoutByFrequency = true {C2 product} intx BlockLayoutMinDiamondPercentage = 20 {C2 product} bool BlockLayoutRotateLoops = true {C2 product} bool BranchOnRegister = false {C2 product} bool BytecodeVerificationLocal = false {product} bool BytecodeVerificationRemote = true {product} bool C1OptimizeVirtualCallProfiling = true {C1 product} bool C1ProfileBranches = true {C1 product} bool C1ProfileCalls = true {C1 product} bool C1ProfileCheckcasts = true {C1 product} bool C1ProfileInlinedCalls = true {C1 product} bool C1ProfileVirtualCalls = true {C1 product} bool C1UpdateMethodData = true {C1 product} intx CICompilerCount := 4 {product} bool CICompilerCountPerCPU = true {product} bool CITime = false {product} bool CMSAbortSemantics = false {product} uintx CMSAbortablePrecleanMinWorkPerIteration = 100 {product} intx CMSAbortablePrecleanWaitMillis = 100 {manageable} uintx CMSBitMapYieldQuantum = 10485760 {product} uintx CMSBootstrapOccupancy = 50 {product} bool CMSClassUnloadingEnabled = true {product} uintx CMSClassUnloadingMaxInterval = 0 {product} bool CMSCleanOnEnter = true {product} bool CMSCompactWhenClearAllSoftRefs = true {product} uintx CMSConcMarkMultiple = 32 {product} bool CMSConcurrentMTEnabled = true {product} uintx CMSCoordinatorYieldSleepCount = 10 {product} bool CMSDumpAtPromotionFailure = false {product} bool CMSEdenChunksRecordAlways = true {product} uintx CMSExpAvgFactor = 50 {product} bool CMSExtrapolateSweep = false {product} uintx CMSFullGCsBeforeCompaction = 0 {product} uintx CMSIncrementalDutyCycle = 10 {product} uintx CMSIncrementalDutyCycleMin = 0 {product} bool CMSIncrementalMode = false {product} uintx CMSIncrementalOffset = 0 {product} bool CMSIncrementalPacing = true {product} uintx CMSIncrementalSafetyFactor = 10 {product} uintx CMSIndexedFreeListReplenish = 4 {product} intx CMSInitiatingOccupancyFraction = -1 {product} uintx CMSIsTooFullPercentage = 98 {product} double CMSLargeCoalSurplusPercent = 0.950000 {product} double CMSLargeSplitSurplusPercent = 1.000000 {product} bool CMSLoopWarn = false {product} uintx CMSMaxAbortablePrecleanLoops = 0 {product} intx CMSMaxAbortablePrecleanTime = 5000 {product} uintx CMSOldPLABMax = 1024 {product} uintx CMSOldPLABMin = 16 {product} uintx CMSOldPLABNumRefills = 4 {product} uintx CMSOldPLABReactivityFactor = 2 {product} bool CMSOldPLABResizeQuicker = false {product} uintx CMSOldPLABToleranceFactor = 4 {product} bool CMSPLABRecordAlways = true {product} uintx CMSParPromoteBlocksToClaim = 16 {product} bool CMSParallelInitialMarkEnabled = true {product} bool CMSParallelRemarkEnabled = true {product} bool CMSParallelSurvivorRemarkEnabled = true {product} uintx CMSPrecleanDenominator = 3 {product} uintx CMSPrecleanIter = 3 {product} uintx CMSPrecleanNumerator = 2 {product} bool CMSPrecleanRefLists1 = true {product} bool CMSPrecleanRefLists2 = false {product} bool CMSPrecleanSurvivors1 = false {product} bool CMSPrecleanSurvivors2 = true {product} uintx CMSPrecleanThreshold = 1000 {product} bool CMSPrecleaningEnabled = true {product} bool CMSPrintChunksInDump = false {product} bool CMSPrintEdenSurvivorChunks = false {product} bool CMSPrintObjectsInDump = false {product} uintx CMSRemarkVerifyVariant = 1 {product} bool CMSReplenishIntermediate = true {product} uintx CMSRescanMultiple = 32 {product} uintx CMSSamplingGrain = 16384 {product} bool CMSScavengeBeforeRemark = false {product} uintx CMSScheduleRemarkEdenPenetration = 50 {product} uintx CMSScheduleRemarkEdenSizeThreshold = 2097152 {product} uintx CMSScheduleRemarkSamplingRatio = 5 {product} double CMSSmallCoalSurplusPercent = 1.050000 {product} double CMSSmallSplitSurplusPercent = 1.100000 {product} bool CMSSplitIndexedFreeListBlocks = true {product} intx CMSTriggerInterval = -1 {manageable} uintx CMSTriggerRatio = 80 {product} intx CMSWaitDuration = 2000 {manageable} uintx CMSWorkQueueDrainThreshold = 10 {product} bool CMSYield = true {product} uintx CMSYieldSleepCount = 0 {product} uintx CMSYoungGenPerWorker = 67108864 {pd product} uintx CMS_FLSPadding = 1 {product} uintx CMS_FLSWeight = 75 {product} uintx CMS_SweepPadding = 1 {product} uintx CMS_SweepTimerThresholdMillis = 10 {product} uintx CMS_SweepWeight = 75 {product} bool CheckEndorsedAndExtDirs = false {product} bool CheckJNICalls = false {product} bool ClassUnloading = true {product} bool ClassUnloadingWithConcurrentMark = true {product} intx ClearFPUAtPark = 0 {product} bool ClipInlining = true {product} uintx CodeCacheExpansionSize = 65536 {pd product} uintx CodeCacheMinimumFreeSpace = 512000 {product} bool CollectGen0First = false {product} bool CompactFields = true {product} intx CompilationPolicyChoice = 3 {product} ccstrlist CompileCommand = {product} ccstr CompileCommandFile = {product} ccstrlist CompileOnly = {product} intx CompileThreshold = 10000 {pd product} bool CompilerThreadHintNoPreempt = true {product} intx CompilerThreadPriority = -1 {product} intx CompilerThreadStackSize = 0 {pd product} uintx CompressedClassSpaceSize = 1073741824 {product} uintx ConcGCThreads = 0 {product} intx ConditionalMoveLimit = 3 {C2 pd product} intx ContendedPaddingWidth = 128 {product} bool ConvertSleepToYield = true {pd product} bool ConvertYieldToSleep = false {product} bool CrashOnOutOfMemoryError = false {product} bool CreateMinidumpOnCrash = false {product} bool CriticalJNINatives = true {product} bool DTraceAllocProbes = false {product} bool DTraceMethodProbes = false {product} bool DTraceMonitorProbes = false {product} bool Debugging = false {product} uintx DefaultMaxRAMFraction = 4 {product} intx DefaultThreadPriority = -1 {product} intx DeferPollingPageLoopCount = -1 {product} intx DeferThrSuspendLoopCount = 4000 {product} bool DeoptimizeRandom = false {product} bool DisableAttachMechanism = false {product} bool DisableExplicitGC = false {product} bool DisplayVMOutputToStderr = false {product} bool DisplayVMOutputToStdout = false {product} bool DoEscapeAnalysis = true {C2 product} bool DontCompileHugeMethods = true {product} bool DontYieldALot = false {pd product} ccstr DumpLoadedClassList = {product} bool DumpReplayDataOnError = true {product} bool DumpSharedSpaces = false {product} bool EagerXrunInit = false {product} intx EliminateAllocationArraySizeLimit = 64 {C2 product} bool EliminateAllocations = true {C2 product} bool EliminateAutoBox = true {C2 product} bool EliminateLocks = true {C2 product} bool EliminateNestedLocks = true {C2 product} intx EmitSync = 0 {product} bool EnableContended = true {product} bool EnableResourceManagementTLABCache = true {product} bool EnableSharedLookupCache = true {product} bool EnableTracing = false {product} uintx ErgoHeapSizeLimit = 0 {product} ccstr ErrorFile = {product} ccstr ErrorReportServer = {product} double EscapeAnalysisTimeout = 20.000000 {C2 product} bool EstimateArgEscape = true {product} bool ExitOnOutOfMemoryError = false {product} bool ExplicitGCInvokesConcurrent = false {product} bool ExplicitGCInvokesConcurrentAndUnloadsClasses = false {product} bool ExtendedDTraceProbes = false {product} ccstr ExtraSharedClassListFile = {product} bool FLSAlwaysCoalesceLarge = false {product} uintx FLSCoalescePolicy = 2 {product} double FLSLargestBlockCoalesceProximity = 0.990000 {product} bool FailOverToOldVerifier = true {product} bool FastTLABRefill = true {product} intx FenceInstruction = 0 {ARCH product} intx FieldsAllocationStyle = 1 {product} bool FilterSpuriousWakeups = true {product} ccstr FlightRecorderOptions = {product} bool ForceNUMA = false {product} bool ForceTimeHighResolution = false {product} intx FreqInlineSize = 325 {pd product} double G1ConcMarkStepDurationMillis = 10.000000 {product} uintx G1ConcRSHotCardLimit = 4 {product} uintx G1ConcRSLogCacheSize = 10 {product} intx G1ConcRefinementGreenZone = 0 {product} intx G1ConcRefinementRedZone = 0 {product} intx G1ConcRefinementServiceIntervalMillis = 300 {product} uintx G1ConcRefinementThreads = 0 {product} intx G1ConcRefinementThresholdStep = 0 {product} intx G1ConcRefinementYellowZone = 0 {product} uintx G1ConfidencePercent = 50 {product} uintx G1HeapRegionSize = 0 {product} uintx G1HeapWastePercent = 5 {product} uintx G1MixedGCCountTarget = 8 {product} intx G1RSetRegionEntries = 0 {product} uintx G1RSetScanBlockSize = 64 {product} intx G1RSetSparseRegionEntries = 0 {product} intx G1RSetUpdatingPauseTimePercent = 10 {product} intx G1RefProcDrainInterval = 10 {product} uintx G1ReservePercent = 10 {product} uintx G1SATBBufferEnqueueingThresholdPercent = 60 {product} intx G1SATBBufferSize = 1024 {product} intx G1UpdateBufferSize = 256 {product} bool G1UseAdaptiveConcRefinement = true {product} uintx GCDrainStackTargetSize = 64 {product} uintx GCHeapFreeLimit = 2 {product} uintx GCLockerEdenExpansionPercent = 5 {product} bool GCLockerInvokesConcurrent = false {product} uintx GCLogFileSize = 8192 {product} uintx GCPauseIntervalMillis = 0 {product} uintx GCTaskTimeStampEntries = 200 {product} uintx GCTimeLimit = 98 {product} uintx GCTimeRatio = 99 {product} uintx HeapBaseMinAddress = 2147483648 {pd product} bool HeapDumpAfterFullGC = false {manageable} bool HeapDumpBeforeFullGC = false {manageable} bool HeapDumpOnOutOfMemoryError = false {manageable} ccstr HeapDumpPath = {manageable} uintx HeapFirstMaximumCompactionCount = 3 {product} uintx HeapMaximumCompactionInterval = 20 {product} uintx HeapSizePerGCThread = 87241520 {product} bool IgnoreEmptyClassPaths = false {product} bool IgnoreUnrecognizedVMOptions = false {product} uintx IncreaseFirstTierCompileThresholdAt = 50 {product} bool IncrementalInline = true {C2 product} uintx InitialBootClassLoaderMetaspaceSize = 4194304 {product} uintx InitialCodeCacheSize = 2555904 {pd product} uintx InitialHeapSize := 251658240 {product} uintx InitialRAMFraction = 64 {product} uintx InitialSurvivorRatio = 8 {product} uintx InitialTenuringThreshold = 7 {product} uintx InitiatingHeapOccupancyPercent = 45 {product} bool Inline = true {product} ccstr InlineDataFile = {product} intx InlineSmallCode = 2000 {pd product} bool InlineSynchronizedMethods = true {C1 product} bool InsertMemBarAfterArraycopy = true {C2 product} intx InteriorEntryAlignment = 16 {C2 pd product} intx InterpreterProfilePercentage = 33 {product} bool JNIDetachReleasesMonitors = true {product} bool JavaMonitorsInStackTrace = true {product} intx JavaPriority10_To_OSPriority = -1 {product} intx JavaPriority1_To_OSPriority = -1 {product} intx JavaPriority2_To_OSPriority = -1 {product} intx JavaPriority3_To_OSPriority = -1 {product} intx JavaPriority4_To_OSPriority = -1 {product} intx JavaPriority5_To_OSPriority = -1 {product} intx JavaPriority6_To_OSPriority = -1 {product} intx JavaPriority7_To_OSPriority = -1 {product} intx JavaPriority8_To_OSPriority = -1 {product} intx JavaPriority9_To_OSPriority = -1 {product} bool LIRFillDelaySlots = false {C1 pd product} uintx LargePageHeapSizeThreshold = 134217728 {product} uintx LargePageSizeInBytes = 0 {product} bool LazyBootClassLoader = true {product} intx LiveNodeCountInliningCutoff = 40000 {C2 product} bool LogCommercialFeatures = false {product} intx LoopMaxUnroll = 16 {C2 product} intx LoopOptsCount = 43 {C2 product} intx LoopUnrollLimit = 60 {C2 pd product} intx LoopUnrollMin = 4 {C2 product} bool LoopUnswitching = true {C2 product} bool ManagementServer = false {product} uintx MarkStackSize = 4194304 {product} uintx MarkStackSizeMax = 536870912 {product} uintx MarkSweepAlwaysCompactCount = 4 {product} uintx MarkSweepDeadRatio = 1 {product} intx MaxBCEAEstimateLevel = 5 {product} intx MaxBCEAEstimateSize = 150 {product} uintx MaxDirectMemorySize = 0 {product} bool MaxFDLimit = true {product} uintx MaxGCMinorPauseMillis = 4294967295 {product} uintx MaxGCPauseMillis = 4294967295 {product} uintx MaxHeapFreeRatio = 100 {manageable} uintx MaxHeapSize := 4009754624 {product} intx MaxInlineLevel = 9 {product} intx MaxInlineSize = 35 {product} intx MaxJNILocalCapacity = 65536 {product} intx MaxJavaStackTraceDepth = 1024 {product} intx MaxJumpTableSize = 65000 {C2 product} intx MaxJumpTableSparseness = 5 {C2 product} intx MaxLabelRootDepth = 1100 {C2 product} intx MaxLoopPad = 15 {C2 product} uintx MaxMetaspaceExpansion = 5451776 {product} uintx MaxMetaspaceFreeRatio = 70 {product} uintx MaxMetaspaceSize = 4294901760 {product} uintx MaxNewSize := 1336410112 {product} intx MaxNodeLimit = 75000 {C2 product} uint64_t MaxRAM = 0 {pd product} uintx MaxRAMFraction = 4 {product} intx MaxRecursiveInlineLevel = 1 {product} uintx MaxTenuringThreshold = 15 {product} intx MaxTrivialSize = 6 {product} intx MaxVectorSize = 16 {C2 product} uintx MetaspaceSize = 21807104 {pd product} bool MethodFlushing = true {product} uintx MinHeapDeltaBytes := 524288 {product} uintx MinHeapFreeRatio = 0 {manageable} intx MinInliningThreshold = 250 {product} intx MinJumpTableSize = 10 {C2 pd product} uintx MinMetaspaceExpansion = 339968 {product} uintx MinMetaspaceFreeRatio = 40 {product} uintx MinRAMFraction = 2 {product} uintx MinSurvivorRatio = 3 {product} uintx MinTLABSize = 2048 {product} intx MonitorBound = 0 {product} bool MonitorInUseLists = false {product} intx MultiArrayExpandLimit = 6 {C2 product} bool MustCallLoadClassInternal = false {product} uintx NUMAChunkResizeWeight = 20 {product} uintx NUMAInterleaveGranularity = 2097152 {product} uintx NUMAPageScanRate = 256 {product} uintx NUMASpaceResizeRate = 1073741824 {product} bool NUMAStats = false {product} ccstr NativeMemoryTracking = off {product} bool NeedsDeoptSuspend = false {pd product} bool NeverActAsServerClassMachine = false {pd product} bool NeverTenure = false {product} uintx NewRatio = 2 {product} uintx NewSize := 83886080 {product} uintx NewSizeThreadIncrease = 5320 {pd product} intx NmethodSweepActivity = 10 {product} intx NmethodSweepCheckInterval = 5 {product} intx NmethodSweepFraction = 16 {product} intx NodeLimitFudgeFactor = 2000 {C2 product} uintx NumberOfGCLogFiles = 0 {product} intx NumberOfLoopInstrToAlign = 4 {C2 product} intx ObjectAlignmentInBytes = 8 {lp64_product} uintx OldPLABSize = 1024 {product} uintx OldPLABWeight = 50 {product} uintx OldSize := 167772160 {product} bool OmitStackTraceInFastThrow = true {product} ccstrlist OnError = {product} ccstrlist OnOutOfMemoryError = {product} intx OnStackReplacePercentage = 140 {pd product} bool OptimizeFill = true {C2 product} bool OptimizePtrCompare = true {C2 product} bool OptimizeStringConcat = true {C2 product} bool OptoBundling = false {C2 pd product} intx OptoLoopAlignment = 16 {pd product} bool OptoScheduling = false {C2 pd product} uintx PLABWeight = 75 {product} bool PSChunkLargeArrays = true {product} intx ParGCArrayScanChunk = 50 {product} uintx ParGCDesiredObjsFromOverflowList = 20 {product} bool ParGCTrimOverflow = true {product} bool ParGCUseLocalOverflow = false {product} uintx ParallelGCBufferWastePct = 10 {product} uintx ParallelGCThreads = 8 {product} bool ParallelGCVerbose = false {product} uintx ParallelOldDeadWoodLimiterMean = 50 {product} uintx ParallelOldDeadWoodLimiterStdDev = 80 {product} bool ParallelRefProcBalancingEnabled = true {product} bool ParallelRefProcEnabled = false {product} bool PartialPeelAtUnsignedTests = true {C2 product} bool PartialPeelLoop = true {C2 product} intx PartialPeelNewPhiDelta = 0 {C2 product} uintx PausePadding = 1 {product} intx PerBytecodeRecompilationCutoff = 200 {product} intx PerBytecodeTrapLimit = 4 {product} intx PerMethodRecompilationCutoff = 400 {product} intx PerMethodTrapLimit = 100 {product} bool PerfAllowAtExitRegistration = false {product} bool PerfBypassFileSystemCheck = false {product} intx PerfDataMemorySize = 32768 {product} intx PerfDataSamplingInterval = 50 {product} ccstr PerfDataSaveFile = {product} bool PerfDataSaveToFile = false {product} bool PerfDisableSharedMem = false {product} intx PerfMaxStringConstLength = 1024 {product} intx PreInflateSpin = 10 {pd product} bool PreferInterpreterNativeStubs = false {pd product} intx PrefetchCopyIntervalInBytes = 576 {product} intx PrefetchFieldsAhead = 1 {product} intx PrefetchScanIntervalInBytes = 576 {product} bool PreserveAllAnnotations = false {product} bool PreserveFramePointer = false {pd product} uintx PretenureSizeThreshold = 0 {product} bool PrintAdaptiveSizePolicy = false {product} bool PrintCMSInitiationStatistics = false {product} intx PrintCMSStatistics = 0 {product} bool PrintClassHistogram = false {manageable} bool PrintClassHistogramAfterFullGC = false {manageable} bool PrintClassHistogramBeforeFullGC = false {manageable} bool PrintCodeCache = false {product} bool PrintCodeCacheOnCompilation = false {product} bool PrintCommandLineFlags = false {product} bool PrintCompilation = false {product} bool PrintConcurrentLocks = false {manageable} intx PrintFLSCensus = 0 {product} intx PrintFLSStatistics = 0 {product} bool PrintFlagsFinal := true {product} bool PrintFlagsInitial = false {product} bool PrintGC = false {manageable} bool PrintGCApplicationConcurrentTime = false {product} bool PrintGCApplicationStoppedTime = false {product} bool PrintGCCause = true {product} bool PrintGCDateStamps = false {manageable} bool PrintGCDetails = false {manageable} bool PrintGCID = false {manageable} bool PrintGCTaskTimeStamps = false {product} bool PrintGCTimeStamps = false {manageable} bool PrintHeapAtGC = false {product rw} bool PrintHeapAtGCExtended = false {product rw} bool PrintHeapAtSIGBREAK = true {product} bool PrintJNIGCStalls = false {product} bool PrintJNIResolving = false {product} bool PrintOldPLAB = false {product} bool PrintOopAddress = false {product} bool PrintPLAB = false {product} bool PrintParallelOldGCPhaseTimes = false {product} bool PrintPromotionFailure = false {product} bool PrintReferenceGC = false {product} bool PrintSafepointStatistics = false {product} intx PrintSafepointStatisticsCount = 300 {product} intx PrintSafepointStatisticsTimeout = -1 {product} bool PrintSharedArchiveAndExit = false {product} bool PrintSharedDictionary = false {product} bool PrintSharedSpaces = false {product} bool PrintStringDeduplicationStatistics = false {product} bool PrintStringTableStatistics = false {product} bool PrintTLAB = false {product} bool PrintTenuringDistribution = false {product} bool PrintTieredEvents = false {product} bool PrintVMOptions = false {product} bool PrintVMQWaitTime = false {product} bool PrintWarnings = true {product} uintx ProcessDistributionStride = 4 {product} bool ProfileInterpreter = true {pd product} bool ProfileIntervals = false {product} intx ProfileIntervalsTicks = 100 {product} intx ProfileMaturityPercentage = 20 {product} bool ProfileVM = false {product} bool ProfilerPrintByteCodeStatistics = false {product} bool ProfilerRecordPC = false {product} uintx PromotedPadding = 3 {product} uintx QueuedAllocationWarningCount = 0 {product} uintx RTMRetryCount = 5 {ARCH product} bool RangeCheckElimination = true {product} intx ReadPrefetchInstr = 0 {ARCH product} bool ReassociateInvariants = true {C2 product} bool ReduceBulkZeroing = true {C2 product} bool ReduceFieldZeroing = true {C2 product} bool ReduceInitialCardMarks = true {C2 product} bool ReduceSignalUsage = false {product} intx RefDiscoveryPolicy = 0 {product} bool ReflectionWrapResolutionErrors = true {product} bool RegisterFinalizersAtInit = true {product} bool RelaxAccessControlCheck = false {product} ccstr ReplayDataFile = {product} bool RequireSharedSpaces = false {product} uintx ReservedCodeCacheSize = 251658240 {pd product} bool ResizeOldPLAB = true {product} bool ResizePLAB = true {product} bool ResizeTLAB = true {pd product} bool RestoreMXCSROnJNICalls = false {product} bool RestrictContended = true {product} bool RewriteBytecodes = true {pd product} bool RewriteFrequentPairs = true {pd product} intx SafepointPollOffset = 256 {C1 pd product} intx SafepointSpinBeforeYield = 2000 {product} bool SafepointTimeout = false {product} intx SafepointTimeoutDelay = 10000 {product} bool ScavengeBeforeFullGC = true {product} intx SelfDestructTimer = 0 {product} uintx SharedBaseAddress = 0 {product} ccstr SharedClassListFile = {product} uintx SharedMiscCodeSize = 122880 {product} uintx SharedMiscDataSize = 4194304 {product} uintx SharedReadOnlySize = 16777216 {product} uintx SharedReadWriteSize = 16777216 {product} bool ShowMessageBoxOnError = false {product} intx SoftRefLRUPolicyMSPerMB = 1000 {product} bool SpecialEncodeISOArray = true {C2 product} bool SplitIfBlocks = true {C2 product} intx StackRedPages = 1 {pd product} intx StackShadowPages = 6 {pd product} bool StackTraceInThrowable = true {product} intx StackYellowPages = 3 {pd product} bool StartAttachListener = false {product} intx StarvationMonitorInterval = 200 {product} bool StressLdcRewrite = false {product} uintx StringDeduplicationAgeThreshold = 3 {product} uintx StringTableSize = 60013 {product} bool SuppressFatalErrorMessage = false {product} uintx SurvivorPadding = 3 {product} uintx SurvivorRatio = 8 {product} intx SuspendRetryCount = 50 {product} intx SuspendRetryDelay = 5 {product} intx SyncFlags = 0 {product} ccstr SyncKnobs = {product} intx SyncVerbose = 0 {product} uintx TLABAllocationWeight = 35 {product} uintx TLABRefillWasteFraction = 64 {product} uintx TLABSize = 0 {product} bool TLABStats = true {product} uintx TLABWasteIncrement = 4 {product} uintx TLABWasteTargetPercent = 1 {product} uintx TargetPLABWastePct = 10 {product} uintx TargetSurvivorRatio = 50 {product} uintx TenuredGenerationSizeIncrement = 20 {product} uintx TenuredGenerationSizeSupplement = 80 {product} uintx TenuredGenerationSizeSupplementDecay = 2 {product} intx ThreadPriorityPolicy = 0 {product} bool ThreadPriorityVerbose = false {product} uintx ThreadSafetyMargin = 52428800 {product} intx ThreadStackSize = 0 {pd product} uintx ThresholdTolerance = 10 {product} intx Tier0BackedgeNotifyFreqLog = 10 {product} intx Tier0InvokeNotifyFreqLog = 7 {product} intx Tier0ProfilingStartPercentage = 200 {product} intx Tier23InlineeNotifyFreqLog = 20 {product} intx Tier2BackEdgeThreshold = 0 {product} intx Tier2BackedgeNotifyFreqLog = 14 {product} intx Tier2CompileThreshold = 0 {product} intx Tier2InvokeNotifyFreqLog = 11 {product} intx Tier3BackEdgeThreshold = 60000 {product} intx Tier3BackedgeNotifyFreqLog = 13 {product} intx Tier3CompileThreshold = 2000 {product} intx Tier3DelayOff = 2 {product} intx Tier3DelayOn = 5 {product} intx Tier3InvocationThreshold = 200 {product} intx Tier3InvokeNotifyFreqLog = 10 {product} intx Tier3LoadFeedback = 5 {product} intx Tier3MinInvocationThreshold = 100 {product} intx Tier4BackEdgeThreshold = 40000 {product} intx Tier4CompileThreshold = 15000 {product} intx Tier4InvocationThreshold = 5000 {product} intx Tier4LoadFeedback = 3 {product} intx Tier4MinInvocationThreshold = 600 {product} bool TieredCompilation = true {pd product} intx TieredCompileTaskTimeout = 50 {product} intx TieredRateUpdateMaxTime = 25 {product} intx TieredRateUpdateMinTime = 1 {product} intx TieredStopAtLevel = 4 {product} bool TimeLinearScan = false {C1 product} bool TraceBiasedLocking = false {product} bool TraceClassLoading = false {product rw} bool TraceClassLoadingPreorder = false {product} bool TraceClassPaths = false {product} bool TraceClassResolution = false {product} bool TraceClassUnloading = false {product rw} bool TraceDynamicGCThreads = false {product} bool TraceGen0Time = false {product} bool TraceGen1Time = false {product} ccstr TraceJVMTI = {product} bool TraceLoaderConstraints = false {product rw} bool TraceMetadataHumongousAllocation = false {product} bool TraceMonitorInflation = false {product} bool TraceParallelOldGCTasks = false {product} intx TraceRedefineClasses = 0 {product} bool TraceSafepointCleanupTime = false {product} bool TraceSharedLookupCache = false {product} bool TraceSuspendWaitFailures = false {product} intx TrackedInitializationLimit = 50 {C2 product} bool TransmitErrorReport = false {product} bool TrapBasedNullChecks = false {pd product} bool TrapBasedRangeChecks = false {C2 pd product} intx TypeProfileArgsLimit = 2 {product} uintx TypeProfileLevel = 111 {pd product} intx TypeProfileMajorReceiverPercent = 90 {C2 product} intx TypeProfileParmsLimit = 2 {product} intx TypeProfileWidth = 2 {product} intx UnguardOnExecutionViolation = 0 {product} bool UnlinkSymbolsALot = false {product} bool Use486InstrsOnly = false {ARCH product} bool UseAES = true {product} bool UseAESIntrinsics = true {product} intx UseAVX = 2 {ARCH product} bool UseAdaptiveGCBoundary = false {product} bool UseAdaptiveGenerationSizePolicyAtMajorCollection = true {product} bool UseAdaptiveGenerationSizePolicyAtMinorCollection = true {product} bool UseAdaptiveNUMAChunkSizing = true {product} bool UseAdaptiveSizeDecayMajorGCCost = true {product} bool UseAdaptiveSizePolicy = true {product} bool UseAdaptiveSizePolicyFootprintGoal = true {product} bool UseAdaptiveSizePolicyWithSystemGC = false {product} bool UseAddressNop = true {ARCH product} bool UseAltSigs = false {product} bool UseAutoGCSelectPolicy = false {product} bool UseBMI1Instructions = true {ARCH product} bool UseBMI2Instructions = false {ARCH product} bool UseBiasedLocking = true {product} bool UseBimorphicInlining = true {C2 product} bool UseBoundThreads = true {product} bool UseCLMUL = true {ARCH product} bool UseCMSBestFit = true {product} bool UseCMSCollectionPassing = true {product} bool UseCMSCompactAtFullCollection = true {product} bool UseCMSInitiatingOccupancyOnly = false {product} bool UseCRC32Intrinsics = true {product} bool UseCodeCacheFlushing = true {product} bool UseCompiler = true {product} bool UseCompilerSafepoints = true {product} bool UseCompressedClassPointers := true {lp64_product} bool UseCompressedOops := true {lp64_product} bool UseConcMarkSweepGC = false {product} bool UseCondCardMark = false {C2 product} bool UseCountLeadingZerosInstruction = true {ARCH product} bool UseCountTrailingZerosInstruction = true {ARCH product} bool UseCountedLoopSafepoints = false {C2 product} bool UseCounterDecay = true {product} bool UseDivMod = true {C2 product} bool UseDynamicNumberOfGCThreads = false {product} bool UseFPUForSpilling = false {C2 product} bool UseFastAccessorMethods = false {product} bool UseFastEmptyMethods = false {product} bool UseFastJNIAccessors = true {product} bool UseFastStosb = false {ARCH product} bool UseG1GC = false {product} bool UseGCLogFileRotation = false {product} bool UseGCOverheadLimit = true {product} bool UseGCTaskAffinity = false {product} bool UseHeavyMonitors = false {product} bool UseInlineCaches = true {product} bool UseInterpreter = true {product} bool UseJumpTables = true {C2 product} bool UseLWPSynchronization = true {product} bool UseLargePages = false {pd product} bool UseLargePagesInMetaspace = false {product} bool UseLargePagesIndividualAllocation := false {pd product} bool UseLockedTracing = false {product} bool UseLoopCounter = true {product} bool UseLoopInvariantCodeMotion = true {C1 product} bool UseLoopPredicate = true {C2 product} bool UseMathExactIntrinsics = true {C2 product} bool UseMaximumCompactionOnSystemGC = true {product} bool UseMembar = false {pd product} bool UseMontgomeryMultiplyIntrinsic = false {C2 product} bool UseMontgomerySquareIntrinsic = false {C2 product} bool UseMulAddIntrinsic = false {C2 product} bool UseMultiplyToLenIntrinsic = true {C2 product} bool UseNUMA = false {product} bool UseNUMAInterleaving = false {product} bool UseNewLongLShift = true {ARCH product} bool UseOSErrorReporting = false {pd product} bool UseOldInlining = true {C2 product} bool UseOnStackReplacement = true {pd product} bool UseOnlyInlinedBimorphic = true {C2 product} bool UseOptoBiasInlining = true {C2 product} bool UsePSAdaptiveSurvivorSizePolicy = true {product} bool UseParNewGC = false {product} bool UseParallelGC := true {product} bool UseParallelOldGC = true {product} bool UsePerfData = true {product} bool UsePopCountInstruction = true {product} bool UseRDPCForConstantTableBase = false {C2 product} bool UseRTMDeopt = false {ARCH product} bool UseRTMLocking = false {ARCH product} bool UseSHA = false {product} bool UseSHA1Intrinsics = false {product} bool UseSHA256Intrinsics = false {product} bool UseSHA512Intrinsics = false {product} intx UseSSE = 4 {product} bool UseSSE42Intrinsics = true {product} bool UseSerialGC = false {product} bool UseSharedSpaces = false {product} bool UseSignalChaining = true {product} bool UseSquareToLenIntrinsic = false {C2 product} bool UseStoreImmI16 = true {ARCH product} bool UseStringDeduplication = false {product} bool UseSuperWord = true {C2 product} bool UseTLAB = true {pd product} bool UseThreadPriorities = true {pd product} bool UseTypeProfile = true {product} bool UseTypeSpeculation = true {C2 product} bool UseUTCFileTimestamp = true {product} bool UseUnalignedLoadStores = false {ARCH product} bool UseVMInterruptibleIO = false {product} bool UseXMMForArrayCopy = false {product} bool UseXmmI2D = true {ARCH product} bool UseXmmI2F = true {ARCH product} bool UseXmmLoadAndClearUpper = true {ARCH product} bool UseXmmRegToRegMoveAll = true {ARCH product} bool VMThreadHintNoPreempt = false {product} intx VMThreadPriority = -1 {product} intx VMThreadStackSize = 0 {pd product} intx ValueMapInitialSize = 11 {C1 product} intx ValueMapMaxLoopSize = 8 {C1 product} intx ValueSearchLimit = 1000 {C2 product} bool VerifyMergedCPBytecodes = true {product} bool VerifySharedSpaces = false {product} intx WorkAroundNPTLTimedWaitHang = 1 {product} uintx YoungGenerationSizeIncrement = 20 {product} uintx YoungGenerationSizeSupplement = 80 {product} uintx YoungGenerationSizeSupplementDecay = 8 {product} uintx YoungPLABSize = 4096 {product} bool ZeroTLAB = false {product} intx hashCode = 5 {product} ================================================ FILE: mvnw ================================================ #!/bin/sh # ---------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # Maven2 Start Up Batch script # # Required ENV vars: # ------------------ # JAVA_HOME - location of a JDK home dir # # Optional ENV vars # ----------------- # M2_HOME - location of maven2's installed home dir # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 # MAVEN_SKIP_RC - flag to disable loading of mavenrc files # ---------------------------------------------------------------------------- if [ -z "$MAVEN_SKIP_RC" ] ; then if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi if [ -f "$HOME/.mavenrc" ] ; then . "$HOME/.mavenrc" fi fi # OS specific support. $var _must_ be set to either true or false. cygwin=false; darwin=false; mingw=false case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home # See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then export JAVA_HOME="`/usr/libexec/java_home`" else export JAVA_HOME="/Library/Java/Home" fi fi ;; esac if [ -z "$JAVA_HOME" ] ; then if [ -r /etc/gentoo-release ] ; then JAVA_HOME=`java-config --jre-home` fi fi if [ -z "$M2_HOME" ] ; then ## resolve links - $0 may be a link to maven's home PRG="$0" # need this for relative symlinks while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG="`dirname "$PRG"`/$link" fi done saveddir=`pwd` M2_HOME=`dirname "$PRG"`/.. # make it fully qualified M2_HOME=`cd "$M2_HOME" && pwd` cd "$saveddir" # echo Using m2 at $M2_HOME fi # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then [ -n "$M2_HOME" ] && M2_HOME=`cygpath --unix "$M2_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi # For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$M2_HOME" ] && M2_HOME="`(cd "$M2_HOME"; pwd)`" [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" fi if [ -z "$JAVA_HOME" ]; then javaExecutable="`which javac`" if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then # readlink(1) is not available as standard on Solaris 10. readLink=`which readlink` if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then if $darwin ; then javaHome="`dirname \"$javaExecutable\"`" javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" else javaExecutable="`readlink -f \"$javaExecutable\"`" fi javaHome="`dirname \"$javaExecutable\"`" javaHome=`expr "$javaHome" : '\(.*\)/bin'` JAVA_HOME="$javaHome" export JAVA_HOME fi fi fi if [ -z "$JAVACMD" ] ; then if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi else JAVACMD="`which java`" fi fi if [ ! -x "$JAVACMD" ] ; then echo "Error: JAVA_HOME is not defined correctly." >&2 echo " We cannot execute $JAVACMD" >&2 exit 1 fi if [ -z "$JAVA_HOME" ] ; then echo "Warning: JAVA_HOME environment variable is not set." fi CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { if [ -z "$1" ] then echo "Path not specified to find_maven_basedir" return 1 fi basedir="$1" wdir="$1" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi # workaround for JBEAP-8937 (on Solaris 10/Sparc) if [ -d "${wdir}" ]; then wdir=`cd "$wdir/.."; pwd` fi # end of workaround done echo "${basedir}" } # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then echo "$(tr -s '\n' ' ' < "$1")" fi } BASE_DIR=`find_maven_basedir "$(pwd)"` if [ -z "$BASE_DIR" ]; then exit 1; fi ########################################################################################## # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central # This allows using the maven wrapper in projects that prohibit checking in binary data. ########################################################################################## if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then if [ "$MVNW_VERBOSE" = true ]; then echo "Found .mvn/wrapper/maven-wrapper.jar" fi else if [ "$MVNW_VERBOSE" = true ]; then echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar" else jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) jarUrl="$value"; break ;; esac done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" if [ "$MVNW_VERBOSE" = true ]; then echo "Downloading from: $jarUrl" fi wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" if $cygwin; then wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` fi if command -v wget > /dev/null; then if [ "$MVNW_VERBOSE" = true ]; then echo "Found wget ... using wget" fi if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then wget "$jarUrl" -O "$wrapperJarPath" else wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" fi elif command -v curl > /dev/null; then if [ "$MVNW_VERBOSE" = true ]; then echo "Found curl ... using curl" fi if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then curl -o "$wrapperJarPath" "$jarUrl" -f else curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f fi else if [ "$MVNW_VERBOSE" = true ]; then echo "Falling back to using Java to download" fi javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" # For Cygwin, switch paths to Windows format before running javac if $cygwin; then javaClass=`cygpath --path --windows "$javaClass"` fi if [ -e "$javaClass" ]; then if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then if [ "$MVNW_VERBOSE" = true ]; then echo " - Compiling MavenWrapperDownloader.java ..." fi # Compiling the Java class ("$JAVA_HOME/bin/javac" "$javaClass") fi if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then # Running the downloader if [ "$MVNW_VERBOSE" = true ]; then echo " - Running MavenWrapperDownloader.java ..." fi ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") fi fi fi fi ########################################################################################## # End of extension ########################################################################################## export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} if [ "$MVNW_VERBOSE" = true ]; then echo $MAVEN_PROJECTBASEDIR fi MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java if $cygwin; then [ -n "$M2_HOME" ] && M2_HOME=`cygpath --path --windows "$M2_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"` [ -n "$MAVEN_PROJECTBASEDIR" ] && MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` fi WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" ================================================ FILE: mvnw.cmd ================================================ @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @REM distributed with this work for additional information @REM regarding copyright ownership. The ASF licenses this file @REM to you under the Apache License, Version 2.0 (the @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM @REM https://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @REM KIND, either express or implied. See the License for the @REM specific language governing permissions and limitations @REM under the License. @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- @REM Maven2 Start Up Batch script @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @REM @REM Optional ENV vars @REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files @REM ---------------------------------------------------------------------------- @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' @echo off @REM set title of command window title %0 @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% @REM set %HOME% to equivalent of $HOME if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") @REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" :skipRcPre @setlocal set ERROR_CODE=0 @REM To isolate internal variables from possible post scripts, we use another setlocal @setlocal @REM ==== START VALIDATION ==== if not "%JAVA_HOME%" == "" goto OkJHome echo. echo Error: JAVA_HOME not found in your environment. >&2 echo Please set the JAVA_HOME variable in your environment to match the >&2 echo location of your Java installation. >&2 echo. goto error :OkJHome if exist "%JAVA_HOME%\bin\java.exe" goto init echo. echo Error: JAVA_HOME is set to an invalid directory. >&2 echo JAVA_HOME = "%JAVA_HOME%" >&2 echo Please set the JAVA_HOME variable in your environment to match the >&2 echo location of your Java installation. >&2 echo. goto error @REM ==== END VALIDATION ==== :init @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". @REM Fallback to current working directory if not found. set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir set EXEC_DIR=%CD% set WDIR=%EXEC_DIR% :findBaseDir IF EXIST "%WDIR%"\.mvn goto baseDirFound cd .. IF "%WDIR%"=="%CD%" goto baseDirNotFound set WDIR=%CD% goto findBaseDir :baseDirFound set MAVEN_PROJECTBASEDIR=%WDIR% cd "%EXEC_DIR%" goto endDetectBaseDir :baseDirNotFound set MAVEN_PROJECTBASEDIR=%EXEC_DIR% cd "%EXEC_DIR%" :endDetectBaseDir IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig @setlocal EnableExtensions EnableDelayedExpansion for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar" FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B ) @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central @REM This allows using the maven wrapper in projects that prohibit checking in binary data. if exist %WRAPPER_JAR% ( echo Found %WRAPPER_JAR% ) else ( if not "%MVNW_REPOURL%" == "" ( SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar" ) echo Couldn't find %WRAPPER_JAR%, downloading it ... echo Downloading from: %DOWNLOAD_URL% powershell -Command "&{"^ "$webclient = new-object System.Net.WebClient;"^ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ "}"^ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ "}" echo Finished downloading %WRAPPER_JAR% ) @REM End of extension %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end :error set ERROR_CODE=1 :end @endlocal & set ERROR_CODE=%ERROR_CODE% if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost @REM check for post script, once with legacy .bat ending and once with .cmd ending if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" :skipRcPost @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' if "%MAVEN_BATCH_PAUSE%" == "on" pause if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% exit /B %ERROR_CODE% ================================================ FILE: pom.xml ================================================ 4.0.0 com.mark JavaBasic 0.0.1-SNAPSHOT jar JavaBasic http://maven.apache.org UTF-8 1.8 junit junit 4.13.1 test commons-io commons-io 2.7 com.maxmind.geoip2 geoip2 2.12.0 com.alibaba fastjson 1.2.83 io.azam.ulidj ulidj 1.0.0 org.apache.maven.plugins maven-compiler-plugin 3.1 1.8 1.8 ================================================ FILE: src/main/java/com/annotation/README.md ================================================ # 按运行机制分类 - 源码注解:注解只在源码中存在,编译成.class文件就不存在了 - 编译时注解:在源码和.class文件中都会存在注解 - 运行时注解:在运行阶段还起作用,甚至韵影像运行逻辑的注解 # 按来源分类 - JDK 中自带的注解 - 第三方的注解 - 我们自定义注解 # 自定义注解 - 自定义注解语法要求 - 注解的注解(元注解) - 使用自定义注解 - 解析注解 ``` package com.sun.org.glassfish.gmbal; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Description { //使用 @interface 来定义注解 String value(); // 成员以无参无异常方式声明 String key() default ""; 可以使用 default 为成员指定一个默认值 } ``` > 成员的类型是受限制的,合法的类型包括Java基本类型及 String, Class, Annotation, Enumeration > > 如果注解只有一个成员,则成员名必须取名为value(), 在使用时可以忽略成员名和赋值号(=) > > 注解类可以没有成员,没有成员的注解可以被称为标识注解 ## 元注解 ``` // 作用范围 public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE } ``` ``` // Retention n. 保留;保持;维持;记忆力 // 生命周期 public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME } ``` ``` @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { } @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { } ``` ## 自定义注解使用 ``` package com.annotation.own; import java.lang.annotation.*; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited // 类之间继承上,接口实现不算 @Documented public @interface Description { String value(); String desc(); String author(); int age() default 18; } ``` # 解析注解 - 通过**反射**获取类,函数或成员上的运行时注解信息,从而实现动态控制程序运行逻辑 # 项目实战 见 project 包中 - 项目取自一个公司的持久层框架,用来代替Hibernete的解决方案,核心代码通过注解来实现 - 需求 - 有一张用户表,字段用户id, 用户名, 昵称, 年龄, 性别, 所在城市, 邮箱, 手机号 - 方便对每个字段或字段组合条件进行检索,并打印出SQL - 使用方式足够简单,见代码实例 - 可以看看 mybatis-plus 的源代码 ================================================ FILE: src/main/java/com/annotation/jdk/Child.java ================================================ package com.annotation.jdk; import com.annotation.own.Description; /** * @Override 这个注解 告诉编译器 / 程序员,方法覆盖接口中方法 * Indicates that a method declaration is intended to override a method declaration in a supertype. * If a method is annotated with this annotation type compilers are required to generate an error * message unless at least one of the following conditions hold: * * The method does override or implement a method declared in a supertype. * The method has a signature that is override-equivalent to that of any public method declared in Object. */ @Description("I am a class annotation.") public class Child implements Person { @Override @Description("I am a method annotation.") public String name() { return null; } @Override public int age() { return 0; } @Override public void sing() { } } ================================================ FILE: src/main/java/com/annotation/jdk/ParseAnnotation.java ================================================ package com.annotation.jdk; import com.annotation.own.Description; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class ParseAnnotation { public static void main(String[] args) { // 1. 使用类加载器加载类 try { Class c = Class.forName("com.annotation.jdk.Child"); // 2. 找到类上的注解 boolean flag = c.isAnnotationPresent(Description.class); if (flag) { // 3. 拿到注解实例 Description description = (Description) c.getAnnotation(Description.class); System.out.println(description.value()); } // 4. 找到方法上的注解 Method[] ms = c.getMethods(); for (Method m : ms) { boolean annotationPresent = m.isAnnotationPresent(Description.class); if (annotationPresent) { Description description = m.getAnnotation(Description.class); System.out.println(description.value()); } } // 5. 另一种解析方法 for (Method m : ms) { Annotation[] as = m.getAnnotations(); for (Annotation a : as) { if (a instanceof Description) { Description description = (Description) a; System.out.println(description.value()); } } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/annotation/jdk/Person.java ================================================ package com.annotation.jdk; /** * Java 注解从 Java 5开始 * @Deprecated 已过时;被废弃 * A program element annotated @Deprecated is one that programmers are discouraged from using, * typically because it is dangerous, or because a better alternative exists. Compilers warn * when a deprecated program element is used or overridden in non-deprecated code. */ public interface Person { public String name(); public int age(); @Deprecated public void sing(); } ================================================ FILE: src/main/java/com/annotation/jdk/Test.java ================================================ package com.annotation.jdk; /** * @SuppressWarnings suppress v. 抑制,压制,阻止 * Indicates that the named compiler warnings should be suppressed in the annotated element * (and in all program elements contained in the annotated element). Note that the set of warnings * suppressed in a given element is a superset of the warnings suppressed in all containing elements. * For example, if you annotate a class to suppress one warning and annotate a method to suppress another, * both warnings will be suppressed in the method. * * As a matter of style, programmers should always use this annotation on the most deeply nested element * where it is effective. If you want to suppress a warning in a particular method, you should annotate * that method rather than its class. */ public class Test { @SuppressWarnings("deprecation") public void sing(String[] args) { Person p = new Child(); p.sing(); } } ================================================ FILE: src/main/java/com/annotation/own/Description.java ================================================ package com.annotation.own; import java.lang.annotation.*; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Description { String value() default ""; } ================================================ FILE: src/main/java/com/annotation/project/Column.java ================================================ package com.annotation.project; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String value(); } ================================================ FILE: src/main/java/com/annotation/project/Department.java ================================================ package com.annotation.project; @Table("t_department") public class Department { @Column("id") private int id; @Column("name") private String name; @Column("leader") private String leader; @Column("amount") private int amount; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLeader() { return leader; } public void setLeader(String leader) { this.leader = leader; } public int getAmount() { return amount; } public void setAmout(int amount) { this.amount = amount; } } ================================================ FILE: src/main/java/com/annotation/project/Table.java ================================================ package com.annotation.project; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Table { String value(); } ================================================ FILE: src/main/java/com/annotation/project/Test.java ================================================ package com.annotation.project; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test { public static void main(String[] args) { User u1 = new User(); u1.setId(10); // 查询 id 为10的用户 User u2 = new User(); u2.setUserName("lucy"); // 模糊查询用户名为 lucy 的用户 User u3 = new User(); u2.setEmail("mark@gmail.com,puma@163.com"); // 查询任意一个邮箱 String sql1 = query(u1); String sql2 = query(u2); String sql3 = query(u3); System.out.println(sql1); System.out.println(sql2); System.out.println(sql3); Department d = new Department(); d.setId(10); d.setLeader("张三丰"); System.out.println(query(d)); } private static String query(Object u) { StringBuilder sb = new StringBuilder(); // 1. 获取 class Class c = u.getClass(); // 2. 获取 table 名字 boolean exist = c.isAnnotationPresent(Table.class); if (!exist) { return null; } Table table = (Table) c.getAnnotation(Table.class); String tableName = table.value(); sb.append("SELECT * FROM ").append(tableName).append(" WHERE 1=1"); // 遍历所有的字段 Field[] declaredFields = c.getDeclaredFields(); for (Field f : declaredFields) { // 处理字段对应的 SQL // 拿到字段的名字 boolean annotationPresent = f.isAnnotationPresent(Column.class); if (!annotationPresent) { continue; } Column column = f.getAnnotation(Column.class); String columnName = column.value(); // 拿到字段的值 String fieldName = f.getName(); String method = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Object fieldValue = null; try { Method invokeMethod = c.getMethod(method); fieldValue = invokeMethod.invoke(u); } catch (Exception e) { e.printStackTrace(); } // 拼装 SQL if (fieldValue == null || (fieldValue instanceof Integer && (int) fieldValue == 0)) { continue; } sb.append(" AND ").append(fieldName); if (fieldValue instanceof String) { if (((String) fieldValue).contains(",")) { String[] strings = ((String) fieldValue).split(","); sb.append(" IN ("); // int count = 0; // counter // for (String s : strings) { // ++ count; // sb.append("'").append(s).append("'"); // if (count == strings.length) { // sb.append(")"); // } else { // sb.append(","); // } // } for (String s : strings) { sb.append("'").append(s).append("'").append(","); } sb.deleteCharAt(sb.length() - 1); sb.append(")"); } else { sb.append("=").append("'").append(fieldValue).append("'"); } } else if (fieldValue instanceof Integer) { sb.append("=").append(fieldValue); } } return sb.toString(); } } ================================================ FILE: src/main/java/com/annotation/project/User.java ================================================ package com.annotation.project; @Table("t_user") public class User { @Column("id") private int id; @Column("user_name") private String userName; @Column("nick_name") private String nickName; @Column("age") private int age; @Column("city") private String city; @Column("email") private String email; @Column("mobile") private String mobile; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } } ================================================ FILE: src/main/java/com/art/concurrency/ch01/ConcurrencyTest.java ================================================ package com.art.concurrency.ch01; /** * 1. 循环次数 * 2. 串并行程序实行时间 * 3. Lmbench3 http://www.bitmover.com/lmbench/ 上下文切换的时长 * 4. vmstat 上下文切换的次数 * 5. 如何减少上下文切换 * 无锁并发编程, CAS算法, 使用最少线程, 使用协程 * 无锁并发编程:不同线程处理不同段的数据 */ public class ConcurrencyTest { private static final long count = 100001; public static void main(String[] args) throws InterruptedException { concurrency(); serial(); } private static void serial() { long start = System.currentTimeMillis(); int a = 0; for (long i = 0; i < count; i++) { a += 5; } int b = 0; for (long i = 0; i < count; i++) { b--; } long time = System.currentTimeMillis() - start; System.out.println("serial: " + time); } private static void concurrency() throws InterruptedException { long start = System.currentTimeMillis(); Thread thread = new Thread(new Runnable() { @Override public void run() { int a = 0; for (long i = 0; i < count; i++) { a += 5; } } }); thread.start(); int b = 0; for (long i = 0; i < count; i++) { b--; } long time = System.currentTimeMillis() - start; thread.join(); System.out.println("concurrency: " + time); } } ================================================ FILE: src/main/java/com/art/concurrency/ch01/DeadLockDemo.java ================================================ package com.art.concurrency.ch01; public class DeadLockDemo { private static String A = "A"; private static String B = "B"; public static void main(String[] args) { new DeadLockDemo().deadLock(); } private void deadLock() { Thread t1 = new Thread(new Runnable() { @Override public void run() { synchronized (A) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (B) { System.out.println("1"); } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { synchronized (B) { try { Thread.sleep(9000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (A) { System.out.println("2"); } } } }); t1.start(); t2.start(); } } ================================================ FILE: src/main/java/com/art/concurrency/ch04/Daemon.java ================================================ package com.art.concurrency.ch04; import com.art.concurrency.utils.SleepUtils; public class Daemon { public static void main(String[] args) { Thread thread = new Thread(new DaemonRunner(), "DaemonRunner"); thread.setDaemon(Boolean.TRUE); thread.start(); } static class DaemonRunner implements Runnable { @Override public void run() { SleepUtils.second(10); } } } ================================================ FILE: src/main/java/com/art/concurrency/ch04/Deprecated.java ================================================ package com.art.concurrency.ch04; import com.art.concurrency.utils.SleepUtils; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.TimeUnit; public class Deprecated { public static void main(String[] args) throws InterruptedException { DateFormat format = new SimpleDateFormat("HH:mm:ss"); Thread printThread = new Thread(new Runner(), "printThread"); printThread.setDaemon(true); printThread.start(); TimeUnit.SECONDS.sleep(3); printThread.suspend(); // 线程暂停 System.out.println("main suspend PrintThread at " + format.format(new Date())); TimeUnit.SECONDS.sleep(3); printThread.resume(); // 线程恢复 System.out.println("main resume PrintThread at " + format.format(new Date())); TimeUnit.SECONDS.sleep(3); printThread.stop(); // 线程停止 System.out.println("main stop PrintThread at " + format.format(new Date())); TimeUnit.SECONDS.sleep(3); } static class Runner implements Runnable { @Override public void run() { DateFormat format = new SimpleDateFormat("HH:mm:ss"); while (true) { System.out.println(Thread.currentThread().getName() + " Run at " + format.format(new Date())); SleepUtils.second(1); } } } } ================================================ FILE: src/main/java/com/art/concurrency/ch04/Interrupted.java ================================================ package com.art.concurrency.ch04; import com.art.concurrency.utils.SleepUtils; import java.util.concurrent.TimeUnit; public class Interrupted { public static void main(String[] args) throws InterruptedException { Thread sleepRunner = new Thread(new SleepRunner(), "SleepRunner"); sleepRunner.setDaemon(true); Thread busyRunner = new Thread(new BusyRunner(), "BusyRunner"); busyRunner.setDaemon(true); sleepRunner.start(); busyRunner.start(); TimeUnit.SECONDS.sleep(5); sleepRunner.interrupt(); busyRunner.interrupt(); System.out.println("SleepThread interrupted is " + sleepRunner.isInterrupted()); System.out.println("BusyThread interrupted is " + busyRunner.isInterrupted()); SleepUtils.second(2); } static class SleepRunner implements Runnable { @Override public void run() { while (true) { SleepUtils.second(10); } } } static class BusyRunner implements Runnable { @Override public void run() { while (true) { } } } } ================================================ FILE: src/main/java/com/art/concurrency/ch04/MultiThread.java ================================================ package com.art.concurrency.ch04; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; public class MultiThread { public static void main(String[] args) { ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false); for (ThreadInfo threadInfo : threadInfos) { System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName()); } } } ================================================ FILE: src/main/java/com/art/concurrency/ch04/Priority.java ================================================ package com.art.concurrency.ch04; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; public class Priority { private static volatile boolean notStart = true; private static volatile boolean notEnd = true; public static void main(String[] args) throws InterruptedException { List jobs = new ArrayList<>(); for (int i = 0; i < 10; i++) { int priority = i < 5 ? Thread.MIN_PRIORITY : Thread.MAX_PRIORITY; Job job = new Job(priority); jobs.add(job); Thread thread = new Thread(job, "thread:" + i); thread.setPriority(priority); thread.start(); } notStart = false; TimeUnit.SECONDS.sleep(10); notEnd = false; for (Job job : jobs) { System.out.println("Job Priority:" + job.priority + ", Count : " + job.jobCount); } } static class Job implements Runnable { private int priority; private long jobCount; public Job() { } public Job(int priority) { this.priority = priority; } public Job(int priority, long jobCount) { this(priority); this.jobCount = jobCount; } @Override public void run() { while (notStart) { Thread.yield(); } while (notEnd) { Thread.yield(); jobCount++; } } } } ================================================ FILE: src/main/java/com/art/concurrency/ch04/Shutdown.java ================================================ package com.art.concurrency.ch04; import java.util.concurrent.TimeUnit; public class Shutdown { public static void main(String[] args) throws InterruptedException { Runner one = new Runner(); Thread countThead = new Thread(one, "CountThread"); countThead.start(); TimeUnit.SECONDS.sleep(1); countThead.interrupt(); Runner two = new Runner(); countThead = new Thread(two, "CountThread"); countThead.start(); TimeUnit.SECONDS.sleep(1); two.cancel(); } static class Runner implements Runnable { private long i; private volatile boolean on = true; @Override public void run() { while (on && !Thread.currentThread().isInterrupted()) { i ++; } System.out.println("Count i = " + i); } public void cancel() { on = false; } } } ================================================ FILE: src/main/java/com/art/concurrency/ch04/ThreadState.java ================================================ package com.art.concurrency.ch04; import com.art.concurrency.utils.SleepUtils; /** * https://docs.oracle.com/javase/8/docs/api/index.html */ public class ThreadState { public static void main(String[] args) { Thread.State[] values = Thread.State.values(); System.out.println(values); new Thread(new TimeWaiting(), "TimeWaitingThread").start(); new Thread(new Waiting(), "WaitingThread").start(); new Thread(new Blocked(), "BlockedThread-1").start(); new Thread(new Blocked(), "BlockedThread-2").start(); } static class TimeWaiting implements Runnable { @Override public void run() { SleepUtils.second(100); } } static class Waiting implements Runnable { @Override public void run() { while (true) { synchronized (Waiting.class) { try { Waiting.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } static class Blocked implements Runnable { @Override public void run() { synchronized (Blocked.class) { while (true) { SleepUtils.second(100); } } } } } ================================================ FILE: src/main/java/com/art/concurrency/ch08/BankWaterService.java ================================================ package com.art.concurrency.ch08; import java.util.Map; import java.util.concurrent.*; public class BankWaterService implements Runnable { /** * 创建四个屏障,处理完之后执行当前类的run方法 */ private CyclicBarrier cyclicBarrier = new CyclicBarrier(4, this); /** * 假设只有四个 sheet 页,所以启动 4 个线程 */ private Executor executor = Executors.newFixedThreadPool(4); /** * 保存每个 sheet 计算出的银行流水结果 */ private ConcurrentHashMap sheetBankWaterCount = new ConcurrentHashMap<>(); private void count() { for (int i = 0; i < 4; i++) { executor.execute(new Runnable() { @Override public void run() { // 计算当前 sheet 的银流数据 sheetBankWaterCount.put(Thread.currentThread().getName(), 1); try { // 计算完成,插入一个屏障 cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); } } @Override public void run() { int result = 0; // 汇总每个 sheet 计算出来的结果 for (Map.Entry sheet : sheetBankWaterCount.entrySet()) { result += sheet.getValue(); } // output sheetBankWaterCount.put("result", result); System.out.println(result); } public static void main(String[] args) { BankWaterService bankWaterService = new BankWaterService(); bankWaterService.count(); } } ================================================ FILE: src/main/java/com/art/concurrency/ch08/CountDownLatchTest.java ================================================ package com.art.concurrency.ch08; import java.util.concurrent.CountDownLatch; public class CountDownLatchTest { // 10 个线程 static CountDownLatch countDownLatch = new CountDownLatch(10); public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { int threadNo = i; new Thread(new Runnable() { @Override public void run() { System.out.println("thread: " + threadNo); // 执行完打印语句之后,count 数减一 countDownLatch.countDown(); } }).start(); } // 当 count 为0时,就可以执行以后的打印语句 countDownLatch.await(); System.out.println("all threads finished."); } } ================================================ FILE: src/main/java/com/art/concurrency/ch08/CyclicBarrierTest.java ================================================ package com.art.concurrency.ch08; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * CyclicBarrier 可用于多线程计算数据,最后合并计算结果的场景。 */ public class CyclicBarrierTest { static CyclicBarrier cyclicBarrier = new CyclicBarrier(2); public static void main(String[] args) throws BrokenBarrierException, InterruptedException { new Thread(new Runnable() { @Override public void run() { try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println(1); } }).start(); cyclicBarrier.await(); System.out.println(2); } } ================================================ FILE: src/main/java/com/art/concurrency/ch08/CyclicBarrierTest02.java ================================================ package com.art.concurrency.ch08; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierTest02 { static CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new A()); public static void main(String[] args) throws BrokenBarrierException, InterruptedException { new Thread(new Runnable() { @Override public void run() { try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println(1); } }).start(); cyclicBarrier.await(); System.out.println(2); } static class A implements Runnable { @Override public void run() { System.out.println(3); } } } ================================================ FILE: src/main/java/com/art/concurrency/ch08/CyclicBarrierTest03.java ================================================ package com.art.concurrency.ch08; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierTest03 { static CyclicBarrier cyclicBarrier = new CyclicBarrier(2); public static void main(String[] args) { Thread t = new Thread(new Runnable() { @Override public void run() { try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); t.start(); t.interrupt(); try { cyclicBarrier.await(); } catch (Exception e) { System.out.println(cyclicBarrier.isBroken()); } } } ================================================ FILE: src/main/java/com/art/concurrency/ch08/ExchangerTest.java ================================================ package com.art.concurrency.ch08; import java.util.concurrent.Exchanger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 用户遗传算法 * 用于校对工作 */ public class ExchangerTest { private static final Exchanger exgr = new Exchanger<>(); private static ExecutorService threadPool = Executors.newFixedThreadPool(2); public static void main(String[] args) { threadPool.execute(new Runnable() { @Override public void run() { try { String a = "银行流水A"; // 同步点,第一个线程执行exchange函数的时候,线程1会等待第二线程也执行 exchange 函数 String msg = exgr.exchange(a); System.out.println("msg=" + msg); } catch (InterruptedException e) { e.printStackTrace(); } } }); threadPool.execute(new Runnable() { @Override public void run() { try { String b = "银行流水B"; String a = exgr.exchange(b); System.out.println("a与b数据是否一致:" + a.equals(b)); System.out.println("A=" + a); System.out.println("B=" + b); } catch (InterruptedException e) { e.printStackTrace(); } } }); threadPool.shutdown(); } } ================================================ FILE: src/main/java/com/art/concurrency/ch08/SemaphoreTest.java ================================================ package com.art.concurrency.ch08; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /** * 可以用作流量控制,特别是公用资源有限的应用场景,如数据库连接。 * 有一个需求,要读取几万个文件的数据,因为是IO密集型任务,我们可以启动几十个线程并发读取 * 但是如果读到内存后,还需要存储到数据库中,而且数据库的连接的连接数只有10个,这时我们必 * 须控制只有10个线程同时获取数据库连接保存数据,否则无法获取数据库连接。 */ public class SemaphoreTest { private static final int THREAD_COUNT = 30; private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT); /** * 最大并发数 10 */ private static Semaphore s = new Semaphore(10); public static void main(String[] args) { for (int i = 0; i < THREAD_COUNT; i++) { threadPool.execute(new Runnable() { @Override public void run() { try { s.acquire(); System.out.println("save data."); s.release(); } catch (InterruptedException e) { e.printStackTrace(); } } }); } threadPool.shutdown(); } } ================================================ FILE: src/main/java/com/art/concurrency/utils/SleepUtils.java ================================================ package com.art.concurrency.utils; import java.util.concurrent.TimeUnit; public class SleepUtils { public static final void second(long seconds) { try { TimeUnit.SECONDS.sleep(seconds); } catch (InterruptedException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/alibaba/BigDecimalTest.java ================================================ package com.basic.alibaba; import java.math.BigDecimal; /** * @description alibaba * @author shenjy * @since 2019/08/04 */ public class BigDecimalTest { public static void main(String[] args) { BigDecimal a = new BigDecimal(0.1); System.out.println(a); // 推荐使用 BigDecimal b = new BigDecimal("0.1"); System.out.println(b); } } ================================================ FILE: src/main/java/com/basic/alibaba/CollectionTest.java ================================================ package com.basic.alibaba; /** * 集合处理 * * @author MarkShen1992 * @since 20200509 */ public class CollectionTest { /* public static void main(String[] args) { List strings = new ArrayList<>(); // 判断所有集合内部的元素是否为空,使用 isEmpty()方法 if (strings.isEmpty()) { System.out.println("集合 strings 为空..."); } strings.add("1"); strings.add("2"); strings.add("3"); List strings1 = strings.subList(0, 2); strings1.forEach(System.out::println); // ArrayList 的 subList 结果不可强转成 ArrayList // java.lang.ClassCastException: java.util.ArrayList$SubList cannot be cast to java.util.ArrayList // ArrayList arrayList = (ArrayList) strings1; // java.lang.UnsupportedOperationException, Returns an empty list (immutable). List ints = Collections.emptyList(); // ints.add(1); List> pairArrayList = new ArrayList<>(3); pairArrayList.add(new Pair<>("version", 6.19)); pairArrayList.add(new Pair<>("version", 10.24)); // 在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常 // pairArrayList.add(new Pair<>("version", null)); Map map = pairArrayList.stream().collect( // 生成的 map 集合中只有一个键值对:{version=13.14} Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v2)); List list = new ArrayList<>(2); list.add("guan"); list.add("bao"); String[] array = list.toArray(new String[0]); int length = array.length; System.out.println(length); // 在使用 Collection 接口任何实现类的 addAll()方法时,都要对输入的集合参数进行 NPE 判断 // Long[] longArr = new Long[] { 1L, 2L, 3L, 4L, 5L, 6L }; List longs = Arrays.asList(longArr); // longs.add(7L); longArr[0] = 11L; // PECS(Producer Extends Consumer Super)原则 // 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/ // 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator // 方式,如果并发操作,需要对 Iterator 对象加锁。 List list2 = new ArrayList<>(); list2.add("1"); list2.add("2"); Iterator iterator = list2.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (item.length() > 0) { iterator.remove(); } } } */ } ================================================ FILE: src/main/java/com/basic/alibaba/ConfusingName.java ================================================ package com.basic.alibaba; /** * @author MarkShen1992 * @since 2020.4.29 */ public class ConfusingName { public int stock; private boolean condition; // 非 setter/getter 的参数名称,不允许与本类成员变量同名 public void get(String alibaba) { if (condition) { final int money = 666; } for (int i = 0; i < 10; i++) { // 在同一方法体中,不允许与其它代码块中的 money 命名相同 final int money = 15978; } } } class Son extends ConfusingName { public int stock; } ================================================ FILE: src/main/java/com/basic/alibaba/DateTest.java ================================================ package com.basic.alibaba; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.util.Date; /** * 日期时间规约 * * @author MarkShen1992 * @since 20200508 */ public class DateTest { private final static String PATTERN = "yyyy-MM-dd HH:mm:ss"; /** * 月 */ private final static int MONTH = 1; /** * 日 */ private final static int DAY = 1; public static void main(String[] args) { String time = "2023-01-04T00:00:00"; System.out.println(time.split("T")[0].replace("-", "/")); DateFormat dateFormat = new SimpleDateFormat(PATTERN); System.out.println(dateFormat.format(new Date())); // 获取当前毫秒数 System.out.println(System.currentTimeMillis()); // 纳秒 System.out.println(System.nanoTime()); // 统计时间等场景 // Instant // 获取今年的天数 int daysOfThisYear = LocalDate.now().lengthOfYear(); System.out.println(daysOfThisYear); // 获取指定某年的天数 System.out.println(getDaysOfCurrentYear(2016)); } private static int getDaysOfCurrentYear(int currentYear) { return LocalDate.of(currentYear, MONTH, DAY).lengthOfYear(); } } ================================================ FILE: src/main/java/com/basic/alibaba/FloatPrimitiveTest.java ================================================ package com.basic.alibaba; /** * @description alibaba * @author shenjy * @since 2019/08/04 */ public class FloatPrimitiveTest { public static void main(String[] args) { float a = 1.0f - 0.9f; float b = 0.9f - 0.8f; if (a == b) { System.out.println("true"); } else { System.out.println("false"); } } } ================================================ FILE: src/main/java/com/basic/alibaba/FloatWrapTest.java ================================================ package com.basic.alibaba; /** * @description alibaba * @author shenjy * @since 2019/08/04 */ public class FloatWrapTest { public static void main(String[] args) { Float a = Float.valueOf(1.0f - 0.9f); Float b = Float.valueOf(0.9f - 0.8f); if (a == b) { System.out.println("true"); } else { System.out.println("false"); } } } ================================================ FILE: src/main/java/com/basic/alibaba/IntegerCacheTest.java ================================================ package com.basic.alibaba; /** * IntegerCacheTest * * @author MarkShen1992 * @since 2020.5.1 */ public class IntegerCacheTest { public static void main(String[] args) { Integer aa = 127; Integer bb = 127; System.out.println(aa.equals(bb)); System.out.println(aa == bb); Integer a = 128; Integer b = 128; System.out.println(a == b); System.out.println(a.equals(b)); int aaa = 128; int bbb = 128; System.out.println(aaa == bbb); Integer c = null; Boolean flag = false; // a*b 的结果是 int 类型,那么 c 会强制拆箱成 int 类型,抛出 NPE 异常 Integer result = (flag ? a * b : c); } } ================================================ FILE: src/main/java/com/basic/alibaba/LockTest.java ================================================ package com.basic.alibaba; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @description alibaba * @author shenjy * @since 2019/08/04 */ public class LockTest { private final static Lock lock = new ReentrantLock(); public static void main(String[] args) { try { lock.tryLock(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } } ================================================ FILE: src/main/java/com/basic/alibaba/PrimitiveTypeArrayMaxSizeTest.java ================================================ package com.basic.alibaba; /** * C:\Users\shenjy>java -version java version "1.8.0_112" Java(TM) SE Runtime Environment (build 1.8.0_112-b15) Java * HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode) */ public class PrimitiveTypeArrayMaxSizeTest { public static void main(String[] args) { // JVM 学习站点: // 1. http://lovestblog.cn/ // 2. https://opts.console.heapdump.cn/ // 3. https://heapdump.cn/ // 注意:这里使用的虚拟机参数:-Xms9g -Xmx9g // Xms: 初始化时候堆大小 // Xmx: 程序运行时堆大小 // char[] chars = new char[Integer.MAX_VALUE - 2]; // System.out.println(chars.length); // byte[] bytes = new byte[Integer.MAX_VALUE - 2]; // System.out.println(bytes.length); // short[] shorts = new short[Integer.MAX_VALUE - 2]; // System.out.println(shorts.length); // int[] ints = new int[Integer.MAX_VALUE - 715784195]; // System.out.println(ints.length); // long[] longs = new long[Integer.MAX_VALUE - 1431633921]; // System.out.println(longs.length); // float[] floats = new float[Integer.MAX_VALUE - 715784195]; // System.out.println(floats.length); // double[] doubles = new double[Integer.MAX_VALUE - 1431633921]; // System.out.println(doubles.length); boolean[] booleans = new boolean[Integer.MAX_VALUE - 2]; System.out.println(booleans.length); } } ================================================ FILE: src/main/java/com/basic/alibaba/SwitchTest.java ================================================ package com.basic.alibaba; /** * @description alibaba * @author shenjy * @since 2019/08/04 */ public class SwitchTest { public static void main(String[] args) { String param = null; switch (param) { case "null": System.out.println("null"); break; default: System.out.println("default"); } } } ================================================ FILE: src/main/java/com/basic/alibaba/package-info.java ================================================ package com.basic.alibaba; /** * @link https://developer.aliyun.com/special/tech-java * 优雅性,可扩展性,可读性 * 分布式事务,分布式消息队列 * 在POJO类里面,方法参数推荐使用包装数据类型,数值计算使用基本数据类型 * 代码质量的度量指标:可读性,可扩展性,可维护性 * 符合开发规范,最合适的地方用最恰当的类的最恰当的方法去处理业务,算法的复杂度,考虑算法的调用频率 * p3c idea插件, eclipse插件 * * 广度和深度 * 首先拓宽自己的广度,然后选择自己擅长的领域去搞 * 推荐读 JDK源码,熟读 API * Dubbo, RocketMQ => 高并发,高可用,分布式 * 多写写原型,像Dubbo原型, RocketMQ原型等 * 保持技术的敏感性,对代码的敏感性 * 修改的代码越多,可扩展性越差 * * (奉献式)热爱,(极致)卓越,思考(主动) */ ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0100Introduction.java ================================================ package com.basic.chapter0100; /** * 简介 * 读书怎么读:看一个大概,直接用,用的时候回来再查 * JDK安装后,看下JDK安装目录 * @author MarkShen1992 * @since 20191101 */ public class Chapter0100Introduction { public static void main(String[] args) { /** * SCM系统 * 电信宽带运营平台 * 远程教学平台 * VOD * 视频监控 * 可视电话 * ERP * 视频会议 * 新闻发布系统 * 网上商城,电子商务 * 移动增值平台 */ /** * 课程内容: * Java基础 * 语法基础 * OO * Exception * Array * 基础类 * I/O stream * Collection/Generic * Thread * TCP/UDP * GUI * MetaData(EJB3.0) * RegExp * 沟通的时候,当你说任何话的时候站在对方角度上考虑下,看他能不能接受 * 没事的时候,多看看数据结构的内容,算法,设计模式 * 数据库的知识 * html,css, javascript, JSP, Servlet * 框架选择,技术选型 * Java Web开发框架 * Hibernate, Mybatis, JPO(掌握原理,算法+数据结构) * 学新东西是件好事儿 * EJB3.0的课程,EJB2.0 * 在招聘网站搜索,招某些职位的量 * 铺网络,上应用 * 教学方法: * 巨无霸式教学 * 理论 * 举例 * 理论回顾 * 联系 * 讲解 * 注重结合工程实践 * 注重传授自学能力 * * 时间短,强度大,这个时候要背一些东西的时候还是要背些内容的 * * 能力的三个层次: * 1. 知识:(接受能力) * 学习前人的东西 * 2. 解决问题的方法:(碰见什么问题,用什么方法) * 灵活运用学到的东西 * 3. 解决问题的思路:(掌握解决问题的思路,拓展一条思路) * 创造解决问题的方法 * 灵活一点儿,再灵活一点 * * 学习方法; * 看算法那本书 * 完成习题 * 运用自学的能力 * 读,写,查,背(*对底子比较薄的同学) * * 预备知识: * 英语 * 计算机基本操作 * 正向的暗示 * Google + 电驴 * 软件行业认证: * 现在开始别听别人忽悠,别听任何人忽悠,别听我忽悠 * 用自己的脑子去认识这个世界 * * 国外比较认软件认证:Oracle认证,CCIE(Cisco Certified Internetwork Expert) * 考含金量比较高的认证 * ERP咨询师 * SAP咨询师 * 共享软件,everything * 努力,勤奋 * 琢磨人,总是要多走一步;走一步看三步,随时留意一些细节 * 身体: * 腰椎,颈椎,手腕 * * 教学资源: * * 企业与学校之间的区别 * 时限 * 使用为主 * * 知识分类: * 实际开发过程中经常要用的知识(牢牢掌握) * 不经常使用用时就可以查到(了解) * 八辈子用不到的知识(运用自己的能里去查) * * 管理好自己的精力 * 乐观的努力 * 眼光要高远一点儿 * 脚步要踏实 * * 问题(老师) * 讲的多,练习时间少 * 只灌输知识点,没有串联 * 不培养自学能力 * 给答案不给思路 * 项目太简单 * 项目太复杂 * 项目太少 * 注重技巧,不重视基本功 * 种管理技巧,请开发技巧 * 知识太旧了 * * 技术 + 行业知识 * 进销存系统 * * Java是解释型语言 * 分层思想 * * 读书怎么读:看一个大概,直接用,用的时候回来再查 */ System.out.println("Hello world!"); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0101Identifier.java ================================================ package com.basic.chapter0100; /** * 标识符 * @author MarkShen1992 * @since 20191101 */ public class Chapter0101Identifier { public static void main(String[] args) { /** * 各种变量,类名,方法名 * * 标识符规则 * 标识符由字母,下划线,数字,美元符号组成 * 标识符由字母,下划线,美元符号开头 * Java标识符大小写敏感,长度无限制 * * 起名字规则:"见名知意",且不能与Java关键词冲突 **/ int result = 10 + 10; System.out.println("hello world, " + result); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0102JavaKeyWord.java ================================================ package com.basic.chapter0100; /** * 关键字 * @author MarkShen1992 * @since 20191101 */ public class Chapter0102JavaKeyWord { public static void main(String[] args) { /** * Java关键字见文章: * https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html */ System.out.println("keyword..."); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0103ConstantAndVariable.java ================================================ package com.basic.chapter0100; /** * 常量与变量 * @author MarkShen1992 * @since 20191101 */ public class Chapter0103ConstantAndVariable { public static void main(String[] args) { /** * 从本质上讲,变量其实就是内存中的一小块区域,使用变量名来访问这块区域, * 因此,每一个变量使用前必须要先声明(申请内存),然后进行赋值(填充内容),才可以使用。 * 不同数据类型所占内存空间不同。 */ int num = 123; // 所在位置,栈内存 double d = 3.14; char ch = 'a'; boolean flag = true; String str = "Hello world!"; // 不可变的变量,类似于C语言中的 const 修饰的量,与Java中的 final 对应 final int var = 10; float PI = 3.14f; // 下面注释掉的这句话会有编译错误 // var = 12; /** * 重点内容:****** * 程序的执行过程:《深入Java虚拟机》,可以找官方英文版 * .exe文件放到操作系统直接执行;.class放到JVM中执行 * 程序首先从硬盘加载(load)到内存区域中 * 然后,操作系统会找到加载到内存中程序的main方法 * 然后,执行过程中的内存管理 * 内存管理中,在程序运行的时候,内存分为4个部分,不同操作系统不同 * 分别是:堆,栈,代码区,方法区 * 堆(Heap):Java代码new出来的东西 * 栈(Stack):局部变量 * 代码区(Code segment):存放代码 * 数据区(Data segment):静态变量,字符串变量 */ } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0104TestVar.java ================================================ package com.basic.chapter0100; /** * 敲程序方法:在看懂整个程序的意思后,背着把程序敲出来; * 或者有自己的理解后,自己组织程序结构完成程序。 * @author MarkShen1992 * @since 20191102 */ public class Chapter0104TestVar { static int j; public void m() { int i = 0; System.out.println(i); } public static void main(String[] args) { int i = 0; System.out.println(i); System.out.println(j); boolean b = false; if(b) { int c = 0; System.out.println("b is true"); } // System.out.println(c); long longNum1 = 8888888888888L; } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0104TestVar2.java ================================================ package com.basic.chapter0100; /** * 数据类型测试 * @author MarkShen1992 * @since 20191102 */ public class Chapter0104TestVar2 { public static void main(String[] args) { boolean b = true; int x, y = 9; double d = 3.1415; char c1, c2; c1 = '\u534e'; c2 = 'c'; x = 12; System.out.println("b=" + b); System.out.println("x=" + x + ",y=" + y); System.out.println("d=" + d); System.out.println("c1=" + c1); System.out.println("c2=" + c2); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0104VariableType.java ================================================ package com.basic.chapter0100; /** * 变量分类 * @author MarkShen1992 * @since 20191101 */ public class Chapter0104VariableType { // 成员变量 static int a; // 成员变量如何初始化的?在什么时候初始化的? public static void main(String[] args) { /** * 按被声明的位置划分: * 成员变量:方法外部,类内部定义的变量 * 局部变量:方法或语句块内部定义的变量 * 注意:类外不能声明变量, 方法的参数叫做局部变量 * * 按所属数据类型划分: * 基本数据类型 * 引用类型 */ // 局部变量 int b = 10; System.out.println(a); System.out.println(b); /** * 变量作用域:在大括号里面声明的变量出了大括号之后就没有人认识它了 */ } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0105DataType.java ================================================ package com.basic.chapter0100; /** * 数据类型 * @author MarkShen1992 * @since 20191102 */ public class Chapter0105DataType { public static void main(String[] args) { /** * 基本数据类型: * 数值型: * 整数类型:byte, short, int, long * 浮点类型:float, double * 字符型(文本):char * Java里面采用Unicode编码,每个字符占两个字节,因而可使用十六进制编码形式表示。 * XML中编码问题 * 每种不同的文字,在计算机中表示为010101... * 每个字节8位 * 中文编码问题 * Unicode一统江湖,统一了全世界所有编码 * https://en.wikipedia.org/wiki/Unicode 需要科学上网 * 布尔型(逻辑):boolean * * 内存大小,小格的布局 * Java各个整数类型有固定的表数范围和字段长度,其不受具体操作系统影响,可以在各个平台移植。 */ /** * 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. * -- 《JVM官方文档》 */ boolean flag = true; if (flag) { System.out.println("flag is valid."); } // 字符型, 占两个字节 char c = 'a'; System.out.println(c); /** * 数类型, 占用内存1个字节, 1byte * Java语言整型常量的三种表示 * 十进制 * 八进制:编码算法中使用,012 * 十六进制 * * Java语言整形常量默认为int类型 */ byte by = 123; System.out.println(by); // 2 bytes short sh = 123; System.out.println(sh); // 4 bytes int num = 123; System.out.println(num); // 8 bytes long lon = 1234L; System.out.println(lon); /** * 浮点类型:浮点数在计算机中的表示,浮点数是有一定的误差的 * float, double * 浮点数默认为 double类型 */ // 8 bytes double PI = 3.14; System.out.println(PI); // 4 bytes, 精度 float PI2 = 3.14f; // float PI2 = 3.14F; System.out.println(PI2); /** * 引用数据类型: * 类(class) * 接口(interface) * 数组(array) */ } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0106BasicDataTypeConvertPrinciple.java ================================================ package com.basic.chapter0100; /** * 基本数据类型转换 * @author MarkShen1992 * @since 20191102 */ public class Chapter0106BasicDataTypeConvertPrinciple { public static void main(String[] args) { /** * 整形,浮点型,字符型的数据在混合运算中相互转换,原则如下: * 1)容量小的数据类型自动转换为容量大的数据类型,数据类型按容量大小(表示的数的大小)排序: * byte, short, char -> int -> long -> float -> double * byte, short, char之间不会相互转换,他们三者在计算前要先转换为 int. * 2)容量大的数据类型转换为容量小的数据类型时,要加上强制转换符,但可能造成 * 精度降低或溢出 * 3)有多种数据类型的数据进行混合运算时,系统首先自动将所有数据转换成容量最大 * 的那一种数据类型,然后再进行计算 * 4)实数类型默认为 double * 5)证书类型默认为 int */ } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0106TestConvert.java ================================================ package com.basic.chapter0100; /** * 练习程序 * @author MarkShen1992 * @since 20191102 */ public class Chapter0106TestConvert { public static void main(String arg[]) { int i1 = 123; int i2 = 456; double d1 = (i1 + i2) * 1.2;// 系统将转换double型进行运算 float f1 = (float) ((i1 + i2) * 1.2);// 需要加强制转换符号 byte b1 = 67; byte b2 = 89; byte b3 = (byte) (b1 + b2);// 系统将转换为 int 进行运算,然后再转换回来 System.out.println(b3); double d2 = 1e200; float f2 = (float) d2;// 产生溢出 System.out.println(f2); float f3 = 1.23f;// 必须加f, 浮点数直接砍掉是不可以的 long l1 = 123; long l2 = 30000000000L;// 必须加L float f = l1 + l2 + f3;// 系统将转换float型计算 long l = (long) f;// 强制转换会舍去小数部分(非四舍五入) } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0106TestConvert2.java ================================================ package com.basic.chapter0100; public class Chapter0106TestConvert2 { public static void main(String[] args) { int i = 1, j = 12; float f1 = (float) 0.1; //0.1f float f2 = 123; long l1 = 12345678, l2 = 8888888888L; double d1 = 2e20, d2 = 124; byte b1 = 1, b2 = 2, b3 = 127; j = j + 10; i = i / 10; // i = i * 0.1; i = (int) (i * 0.1); char c1 = 'a', c2 = 125; byte b = (byte) (b1 - b2); char c = (char) (c1 + c2 - 1); float f3 = f1 + f2; float f4 = (float) (f1 + f2 * 0.1); double d = d1 * i + j; float f = (float) (d1 * 5 + d2); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0107TestIF.java ================================================ package com.basic.chapter0100; /** * if 表达式 * @author MarkShen1992 * @since 20191103 */ public class Chapter0107TestIF { public static void main(String[] args) { int i = 20; if (i < 20) { System.out.println("<20"); System.out.println("<20"); } else if (i < 40) { System.out.println("<40"); } else if (i < 60) { System.out.println("<60"); } else // 当if...else...语句中只有一个语句,可以省略大括号,不推荐使用 System.out.println(">=60"); System.out.println(">=60"); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0108For.java ================================================ package com.basic.chapter0100; /** * for语句, 计算1到 100这100个数之和 * foreach语句打印 * 分析算法时候,分析内存,找到规律。分析别人的算法,多分析别人的程序 * 多读别人的程序,提炼一些好的算法,算法慢慢积累,多看看数学 * * @author MarkShen1992 * @since 20191103 */ public class Chapter0108For { public static void main(String[] args) { long result = 0; for (int i = 1; i <= 100; i ++) { result += i; } System.out.println("result=" + result); foreachTest(); System.out.println("factorial = " + factorialCompute(3)); System.out.println(factorialRecursion(3)); } /** * print the array elements */ public static void foreachTest() { int[] arr = {1, 2, 3, 4}; for (int number : arr) { System.out.println(number); } } /** * 计算 factorial 的阶乘, 1! + 2! + 3! + ... + factorial! * * @param factorial * @return */ public static int factorialCompute(int factorial) { // 好的编程习惯,要对传进来的参数进行判断 if (factorial <= 0) { return 0; } // 最终的一结果 int result = 0; // 临时变量存数 int tmpNum = 1; for (int i = 1; i <= factorial; i++) { tmpNum *= i; result += tmpNum; } return result; } /** * 递归实现阶乘 * * @param factorial * @return */ public static int factorialRecursion(int factorial) { if (factorial <= 0) { return 0; } if (factorial == 1) { return 1; } return factorial * factorialRecursion(-- factorial); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0109TestWhile.java ================================================ package com.basic.chapter0100; /** * while * do...while * * @author MarkShen1992 * @since 20191103 */ public class Chapter0109TestWhile { public static void main(String[] args) { int i = 0; while (i < 10) { System.out.println(i); i++; } i = 0; do { i++; System.out.println(i); } while (i < 10); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0110TestBreakAndContinue.java ================================================ package com.basic.chapter0100; /** * break * continue * * @author MarkShen1992 * @since 20191103 */ public class Chapter0110TestBreakAndContinue { public static void main(String[] args) { breakTest(); continueTest(); } private static void continueTest() { for (int i = 0; i < 10; i ++) { if (i == 6) continue; System.out.println(i); } } private static void breakTest() { for (int i = 0; i < 10; i ++) { if (i == 6) break; System.out.println(i); } } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0111TestSwitch.java ================================================ package com.basic.chapter0100; /** * switch * @author MarkShen1992 * @since 20191103 */ public class Chapter0111TestSwitch { public static void main(String[] args) { int i = 8; switch(i) { // 多个case可以合并到一起 case 8 : case 3 : case 2 : System.out.println("C"); break; case 9 : System.out.println("D"); break; default: // default 可以省略,但是不建议 System.out.println("error"); } // JDK7 new feature 语法 String condition = "abc"; switch(condition) { case "abcd" : System.out.println("abcd"); break; // 不加break,会产生case穿透问题 case "abc" : System.out.println("abc"); break; default: System.out.println("1234"); } } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0112TestMethod.java ================================================ package com.basic.chapter0100; /** * 方法: 增强程序的复用性 * * @author MarkShen1992 * @since 20191103 */ public class Chapter0112TestMethod { public static void main(String[] args) { m(); m2(2); m3('3', 4); m4(4, 6); int i = m4(4, 6); System.out.println(i); } public static void m() { // return; System.out.println("ok"); System.out.println("hello"); } public static void m2(int i) { if (i > 3) return; System.out.println(i); } public static void m3(int i, int j) { System.out.println(i + j); } public static int m4(int i, int j) { return i > j ? i : j; } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0113TestMethod2.java ================================================ package com.basic.chapter0100; /** * method * @author MarkShen1992 * @since 20191103 */ public class Chapter0113TestMethod2 { public int max(int a, int b) { return a > b ? a : b; } public int min(int a, int b) { return a < b ? a : b; } public static void main(String[] args) { Chapter0113TestMethod2 t = new Chapter0113TestMethod2(); System.out.println("Max = " + t.max(3, 4)); System.out.println("Min = " + t.min(3, 4)); // System.out.println(Max(3, 4)); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Chapter0114Fab.java ================================================ package com.basic.chapter0100; public class Chapter0114Fab { public static void main(String[] args) { System.out.println(f(-9)); } public static long f(int index) { if (index < 1) { System.out.println("invalid parameter!"); return -1; } if (index == 1 || index == 2) { return 1; } long f1 = 1L; long f2 = 1L; long f = 0; for (int i = 0; i < index - 2; i++) { f = f1 + f2; f1 = f2; f2 = f; } return f; } } ================================================ FILE: src/main/java/com/basic/chapter0100/Test01.java ================================================ package com.basic.chapter0100; /** * PPT中未敲完的程序 * * @author MarkShen * @since 20191207 */ public class Test01 { public static void main(String[] args) { int i1 = 10, i2 = 20; int i = i2 ++; System.out.println("i=" + i); System.out.println("i2=" + i2); i = ++ i2; System.out.println("i=" + i); System.out.println("i2=" + i2); i = -- i1; System.out.println("i=" + i); System.out.println("i1=" + i1); i = i1 --; System.out.println("i=" + i); System.out.println("i1=" + i1); } } ================================================ FILE: src/main/java/com/basic/chapter0100/Test02.java ================================================ package com.basic.chapter0100; /** * PPT中未敲完的程序 * * @author MarkShen * @since 20191207 */ public class Test02 { public static void main(String[] args) { boolean a, b, c; a = true; b = false; c = a & b; System.out.println("c=" + c); c = a | b; System.out.println("c=" + c); c = a ^ b; System.out.println("c=" + c); c = !a; System.out.println("c=" + c); c = a && b; System.out.println("c=" + c); c = a || b; System.out.println("c=" + c); int i = 1, j = 2; boolean flag1 = (i > 3) && ((i + j) > 5); boolean flag2 = (i < 2) && ((i + j) < 6); // 三目运算符号 int score = 80; String result = score > 60 ? "及格" : "不及格"; System.out.println(result); // fab System.out.println(f(3)); } public static int f(int n) { if (n == 1 || n == 2) { return 1; } else { return f(n - 1) + f(n - 2); } } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0200Introduction.java ================================================ package com.basic.chapter0200; /** * 简介 * 指导性思想(极其重要) * 第一步:考虑问题域中有哪些类,哪些对象 * 第二步:这些个类,这些个对象有哪些个属性 * 第三步:考虑类与类之间的关系,定他们之间的方法 * * 分析问题域方法 * 类,成员变量(属性):找名词 * 方法(函数):找动词 * * 万事万物皆对象 * 追求: * 重用,可扩展性(多态),可维护性,面向组件(二进制级别抽象)的编程,WebService,SOA,COM * * @author MarkShen1992 * @since 20191104 */ public class Chapter0200Introduction { public static void main(String[] args) { /** * 编程语言的发展 * 面向过程设计思想 * 一切以我为中心 * 我第一步要干什么; * 第二步要干什么; * ...... * * 面向对象设计思想 * 车 go(新疆),车怎么去,我不知道,最合适的方法应该出现在最合适的类里面, * 车最知道自己的内部结构。在程序内,不在分解一步一步的过程,而是在问题域 * 里应该有哪些个对象,对象里面应该有哪些属性(静),哪些方法(动),对象 * 与对象之间的关系。 * * 对象和类的概念 * 类是抽象的:具有某些特征的东西。一类事物的抽象。静态的属性 * 瓶子能倒水 * 对象是具体的,对应着数据库中的一条记录 * * 类之间的关系 * 依赖 < 关联(我这个方法的参数是你这个类的对象) < 聚合 < 组合 * 为 设计模式 打基础 * 继承:...是一种..., extends * 聚合:整体与局部的关系,...是...的一部分。 * 组合:密不可分,...是...必不可少的一部分。 * UML图 * 实现关系:implements * 多态: * 存在继承关系; * 方法重写 * 父类引用指向子类对象 * * 对象和引用 * 引用:Java语言中除基本类型之外的变量类型都称为引用类型。 * Java堆内存中的对象是通过栈内存中的引用对其操作的 * 占两块儿内存,堆内存,栈内存 * * Java类的定义 * 构造函数(析构函数) * public 类名() {} * new 一个东西的时候要调用的方法,叫做构造方法。 * 一旦你自己重写构造方法,那么Java 编译器将不会为这个类添加默认的构造方法 * 所以,我们在new对象的时候,我们要做到的就是把那个无参的构造方法 * 手动加上 * * 对象的创建和使用 * Object o = new Object(); * o.equals(new Object); * * this 关键字 * 当前对象 * this(String...) 对应的构造方法 * this.methodName 本类方法 * * super 关键字 * 调用父类的内容 * super(String...) 对应父类构造函数 * super.methodName 父类方法 * * static 关键字 * 类变量 * 类方法 * * package 关键字 * 解决类名冲突的问题 * 命名:公司域名倒过来,默认为default包 * 包对应文件系统中的文件夹 * 根据业务分包 * 根据功能分包 * 如果向让别的人用你的类,首先要先用 import 关键字将其引入 * * import 关键字 * 引入别的类库 * * 访问控制 public protected private 友好 * 对于成员变量如下表: * 修饰符 类内部 同一个包 子类 任何地方 * public Y N N N * default Y Y N N * protected Y Y Y N * public Y Y Y Y * * 对于类来说 * public:任何地方都可以使用这个类 * default * * 类的继承 extends * 特别注意下 protected 关键字 * 双亲委派机制 * 子类对象包含父类对象 * * 方法的重写 @Override * 从父类继承 * 相同的函数名称 * 相同的参数列表 * 相同的方法返回值 * 重写方法的时候要去父类copy, 也可以使用工具生成 * 重写的方法不可以使用比被重写方法更严格的访问权限 * * final 关键字 * 类似于C语言中的 const * 在内存中的 数据 区 * 被 final 修饰的变量不能被修改 * 成员变量 * 局部变量 (形参) * final 的方法不能被重写 * final 的类不能被继承 * * Object 类 * https://docs.oracle.com/javase/8/docs/ * Java 根基类 * 多看JavaAPI * toString() 方法 * equals方法 * * 对象转型 * 父类引用指向子类对象 * 一个基类的引用不可以访问其子类对象新加的成员(属性和方法) * 可以使用 引用变量 instanceof 类名,来判断该引用类型变量所指向的对象是否 * 属于该类或该类的子类 * 子类的对象可以当作基类的对象来使用称上转型(upcasting),反之,称为下转型 * * 扩展性比较好的例子: * 当你建好这个建筑后,或者你写好这个程序之后,把主建筑建好了,将来要加一些 * 其他的功能,尽量不要去修改主结构,叫扩展性好 * 多看 经典建筑方面的书籍,比如巴黎圣母院的重新设计 * * 亮了!巴黎圣母院的新塔尖设计方案 * http://dy.163.com/v2/article/detail/EET5G1F70528UJ6I.html * https://zhuanlan.zhihu.com/p/77317713 * * 多态 * 存在继承关系 * 方法重写 * 父类引用指向子类对象 * 实际中new的谁,就调用谁的方法,函数指针,动态绑定,核心中的核心 * * 抽象类 Abstract * 用 abstract 修饰的类为抽象类, 修饰的方法为 抽象方法 * 抽象方法没有必要实现 * * // 相当于 C ++ 中的纯虚函数 * public abstract void method(); * 当一个类中有抽象方法的时候,那么这个类必须被声明为抽象类,抽象类 * 必须被继承,抽象方法必须被重写 * 抽象类不可以 new 出对象 * 抽象类只需声明,不需要实现 * * 接口 interface implements * 多个无关的类可以实现同一个接口 * 一个类可以实现多个无关的接口 * 与继承关系类似,接口与实现类之间存在多态性 * * 接口是抽象方法和常量值的定义的集合,接口是一种特殊的抽象类,这种抽象类中 * 只包含常量和方法的定义,而没有变量和方法的实现。 * * public static final int id = 1; * 为什么要定义成 public static final 吗?为了修正 c++ 中多继承时候,容易 * 出现问题的地方。c++ 的多继承容易出现:类的多个父类之间,如果有相同的成员 * 变量的时候,引用起来相当麻烦,运行时候产生各种各样的问题。 * * 接口的特性: * 1. 接口可以多重实现 * 2. 接口中声明的属性默认为 public static final 的,也只能是 public static final的 * 3. 接口中只能定义抽象方法,这些接口默认为 public 的,也只能是 public 的 * 4. 接口可以继承其他接口,并添加新的属性和成员方法 * * 接口中定义的方法:函数指针 * * * 总结: * 1. 内存分析贯穿始终 * 2. 对象和类的概念 * 3. 类(对象)之间的关系 * 4. 面向对象设计思想 * 5. class * 6. new * 引用的概念 * 构造方法的概念 * 7. 方法重载 * 构造方法重载 * 8. this * 9. super * 10. static * 11. package & import * 12. private default protected public * 13. extends * 14. override * 15. final * 16. Object * toString * equals * 17. upcasting downcasting * 18. Polymorphism/dynamic binding/late * 19. abstract class * 20. interface * implements */ } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0201OO.java ================================================ package com.basic.chapter0200; /** * * @author MarkShen1992 * @since 20191105 */ public class Chapter0201OO { public static void main(String[] args) { /** * 成员变量 * 可以是Java语言中的任何一种数据类型,基本类型和引用类型 * 在定义成员变量时可以直接对其初始化,如果不对其初始化, * Java将使用默认的值进行初始化 * byte 0 * short 0 * int 0 * long 0L * char '\u0000' * float 0.0F * double 0.0D * boolean false * 引用类型 null * * *成员变量在什么时候对其进行初始化,怎么初始化的? * * 局部变量: * 声明 > 赋值 > 使用 */ } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0202ValueTransferAndReferenceTransfer.java ================================================ package com.basic.chapter0200; /** * 小程序分析内存,清楚理解值传递,引用传递 * * 方法执行完毕,为方法分配的局部变量(stack内存)所分配的内存自动消失 * Heap内存中的内存需要垃圾回收机制来做回收 * * @author MarkShen1992 * @since 20191106 */ public class Chapter0202ValueTransferAndReferenceTransfer { public static void main(String[] args) { Chapter0202ValueTransferAndReferenceTransfer c = new Chapter0202ValueTransferAndReferenceTransfer(); int date = 9; BirthDate bd = new BirthDate(1970, 7, 7 ); BirthDate bd2 = new BirthDate(2000, 1, 1); c.change1(date); System.out.println(date); c.change2(bd); System.out.println(bd); c.change3(bd2); System.out.println(bd2); } public void change1(int i) { i = 1234; } public void change2(BirthDate b) { b = new BirthDate(22, 2, 2004); } public void change3(BirthDate b) { b.setDay(22); } } /** * 出生日期 */ class BirthDate { private int year; private int month; private int day; public BirthDate() {} public BirthDate(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } @Override public String toString() { return "BirthDate{" + "year=" + year + ", month=" + month + ", day=" + day + '}'; } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0203Point.java ================================================ package com.basic.chapter0200; /** * 练习例子 * * @author MarkShen1992 * @since 20191107 */ public class Chapter0203Point { public static void main(String[] args) { Point p = new Point(1, 2, 3); Point p2 = new Point(0, 0, 0); // 函数返回值,在内存中也有一块儿空间 double result = p.getDistance(p2); System.out.println(result); } } class Point { private double x, y, z; public Point() { } public Point(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } public double getZ() { return z; } public void setZ(double z) { this.z = z; } public double getDistance(Point p) { return Math.sqrt( (this.x - p.getX()) * (this.x - p.getX()) + (this.x - p.getX()) * (this.x - p.getX()) + (this.z - p.getZ()) * (this.z - p.getZ()) ); } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0204MethodOverload.java ================================================ package com.basic.chapter0200; /** * 方法重载:指一个类中可以定义有相同的名字,单参数不同的多个方法,调用时会根据参数的不同 * 调用不同的方法。 * 重载方法参数特性: * 个数不同 * 类型不同 * 顺序不同 * * 构造方法,普通方法皆可重载 * * @author MarkShen1992 * @since 20191107 */ public class Chapter0204MethodOverload { public static int add(int a, int b) { return a + b; } // 不与第一个方法产生冲突 // public static void add(int a, int b) { // System.out.println(a + b); // } public static int add(short a, short b) { return a + b; } public static double add(double a, int b) { return a + b; } public static double add(int a, double b) { return a + b; } public static double add(double... args) { double tmpVal = 0; for (int i=0; i radius * radius) return false; else return true; } public void setO(double x, double y) { o.setX(x); o.setY(y); } public Point2 getO() { return o; } public double getRadius() { return radius; } public void setRadius(double r) { radius = r; } public double area() { return 3.14 * radius * radius; } } public class Chapter0206TestCircle { public static void main(String args[]) { Circle c1 = new Circle(new Point2(1.0, 2.0), 2.0); Circle c2 = new Circle(5.0); System.out.println("c1:(" + c1.getO().getX() + "," + c1.getO().getY() + ")," + c1.getRadius()); System.out.println("c2:(" + c2.getO().getX() + "," + c2.getO().getY() + ")," + c2.getRadius()); System.out.println("c1 area = " + c1.area()); System.out.println("c1 area = " + c2.area()); c1.setO(5, 6); c2.setRadius(9.0); System.out.println("c1:(" + c1.getO().getX() + "," + c1.getO().getY() + ")," + c1.getRadius()); System.out.println("c2:(" + c2.getO().getX() + "," + c2.getO().getY() + ")," + c2.getRadius()); System.out.println("c1 area = " + c1.area()); System.out.println("c1 area = " + c2.area()); Point2 p1 = new Point2(5.2, 6.3); System.out.println(c1.contains(p1)); System.out.println(c1.contains(new Point2(10.0, 9.0))); } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0207this.java ================================================ package com.basic.chapter0200; /** * this 关键字 * 在类的方法定义中使用的this关键字代表使用该方法的对象的引用 * 当必须指定当前使用方法的对象是谁的时候用this * 使用this处理类中构造方法中,成员变量和参数重名的问题 * 当前对象的引用 * * @author MarkShen1992 * @since 20191113 */ public class Chapter0207this { int i = 0; /** * 原则:当你确定不了一个参数到底是哪个变量的时候,找离他最近的声明 * */ public Chapter0207this(int i) { this.i = i; } /** * 链式编程 * 返回值在栈空间分配 * * @return */ public Chapter0207this increment() { i ++; return this; } public void print() { System.out.println("i = " + i); } public static void main(String[] args) { Chapter0207this c = new Chapter0207this(1); c.increment().increment().print(); } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0208static.java ================================================ package com.basic.chapter0200; /** * static 关键字 * static 修饰的成员变量为静态成员变量,它为该类的共有变量,在第一次使用时被初始化,对该类的所有 * 对象来说,static 成员变量只有一份。 * 用 static 声明的方法为静态方法,在调用该方法时,不会将对象的引用传给它,所有在静态方法中不可以 * 访问非静态成员。 * 静态方法不再是针对某个对象调用,所以不能访问非静态成员 * 可以通过类名或对象引用调用 static 方法 * * @author MarkShen1992 * @since 20191113 */ public class Chapter0208static { // 存在于内存中数据区,Data Segment,可用于计数 static int i; /** * 静态初始化块 */ static { } public static void print() { System.out.println("hello " + i); } public static void main(String[] args) { Chapter0208static.i = 10; print(); } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0209TestInherit.java ================================================ package com.basic.chapter0200; class FatherClass { public int value; public void f() { value = 100; System.out.println("FatherClass.value=" + value); } } class ChildClass extends FatherClass { public int value; public void f() { super.f(); value = 200; System.out.println("ChildClass.value=" + value); System.out.println(value); System.out.println(super.value); } } /** * super 关键字 * * @author MarkShen1992 * @since 20191117 */ public class Chapter0209TestInherit { public static void main(String[] args) { ChildClass cc = new ChildClass(); cc.f(); } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0210TestEquals.java ================================================ package com.basic.chapter0200; import java.util.Objects; public class Chapter0210TestEquals { public static void main(String[] args) { Cat c1 = new Cat(1, 2, 3); Cat c2 = new Cat(1, 2, 3); System.out.println(c1 == c2); System.out.println(c1.equals(c2)); String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2); System.out.println(s1.equals(s2)); } } class Cat { int color; int height, weight; public Cat(int color, int height, int weight) { this.color = color; this.height = height; this.weight = weight; } public boolean equals(Object obj) { if (obj == null) return false; else { if (obj instanceof Cat) { Cat c = (Cat) obj; if (c.color == this.color && c.height == this.height && c.weight == this.weight) { return true; } } } return false; } @Override public int hashCode() { return Objects.hash(color, height, weight); } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0211TestFinal.java ================================================ package com.basic.chapter0200; public class Chapter0211TestFinal { public static void main(String[] args) { T t = new T(); //t.i = 8; } } final class T { final int i = 8; public final void m() { //j = 9; } } /** * T 是被 final 修饰的类, 不可以被继承 */ //class TT extends T { // //} ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0212TestInterface.java ================================================ package com.basic.chapter0200; /** * 接口测试 * * @author MarkShen1992 * @since 20191120 */ public class Chapter0212TestInterface implements A, B { public static void main(String[] args) { Chapter0212TestInterface t = new Chapter0212TestInterface(); t.print(); A a = new Chapter0212TestInterface(); t.print(a); } @Override public void print() { System.out.println("hello world!"); } @Override public void print(A a) { System.out.println(a); } } interface A { void print(); } interface B { void print(A a); } interface C { void test(); } interface D extends C, A, B { void test(); void sleep(); void sing(); } class F implements D { @Override public void print() { } @Override public void print(A a) { } @Override public void test() { } @Override public void sleep() { } @Override public void sing() { } } ================================================ FILE: src/main/java/com/basic/chapter0200/Chapter0213DoubleBraceInitializationModel.java ================================================ package com.basic.chapter0200; import java.util.UUID; public class Chapter0213DoubleBraceInitializationModel { public static void main(String[] args) { // double brace initialization // https://www.baeldung.com/java-double-brace-initialization // this way can be used in making List, Set, Map, etc. User u = new User() { { setUserId(UUID.randomUUID().toString()); setUserName("shenjy"); setRealName("沈军禹"); } }; System.out.println(u); } } /** * 用户Model */ class User { private String userId; private String userName; private String realName; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } @Override public String toString() { return "User{" + "userId='" + userId + '\'' + ", userName='" + userName + '\'' + ", realName='" + realName + '\'' + '}'; } } ================================================ FILE: src/main/java/com/basic/chapter0200/MessageFormatTest.java ================================================ package com.basic.chapter0200; import java.text.MessageFormat; import java.util.Date; public class MessageFormatTest { public static void main(String[] args) { int planet = 7; String event = "a disturbance in the Force"; String result = MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", planet, new Date(), event); System.out.println(result); } } ================================================ FILE: src/main/java/com/basic/chapter0200/TestSuperSub.java ================================================ package com.basic.chapter0200; class SuperClass { private int n; SuperClass() { System.out.println("SuperClass()"); } SuperClass(int n) { System.out.println("SuperClass(" + n + ")"); this.n = n; } } class SubClass extends SuperClass { private int n; SubClass(int n) { super(); System.out.println("SubClass(" + n + ")"); this.n = n; } SubClass() { super(300); System.out.println("SubClass()"); } } /** * 继承中的构造方法 * 规则: * 1. 子类在构造的时候,要首先调用父类的构造方法 * 2. super 关键字 * 3. 如果调用了 super,必须写在子类构造方法的第一行 * * @author MarkShen1992 * @since 继承中的构造方法 */ public class TestSuperSub { public static void main(String arg[]) { SubClass sc1 = new SubClass(); SubClass sc2 = new SubClass(400); } } ================================================ FILE: src/main/java/com/basic/chapter0300/Chapter0300ExceptionIntroduction.java ================================================ package com.basic.chapter0300; /** * Exception * 异常的概念 * Java异常的分类 * 异常的捕获和处理 * 运行期出现的问题 * * 观察错误的名字和行号特别重要 * 程序是调出来的 * * @author MarkShen1992 * @since 20191121 */ public class Chapter0300ExceptionIntroduction { public static void main(String[] args) { /** * 对于数组越界问题,C, C++ 语言中会有问题,缓冲区溢出漏洞。 * 所以写C, C++ 程序的时候,一定要安全内容 * * Java异常是Java提供的处理程序错误的一种机制 * 所谓错误是指在程序运行的时候发生的一些异常事件 * 设计好的程序应该在发生异常时提供异常处理的方法,使得程序不会因为异常的发生而阻断 * 或产生不可预期的后果。 * Java程序的执行过程中如果出现异常事件,可以生成一个异常对象,该异常对象封装了异常 * 事件的信息,并被提交给Java运行时系统,这个过程称为抛出异常。 * 当Java运行时系统接收到异常对象时,会寻找可以处理异常的方法,并把当前异常对象交给 * 其处理,这个过程称为捕获异常。 * * try() { * ...代码 * } catch (XXXException e) { * 捕获异常后处理 * } catch (YYYException e2) { * ... * } finally { * 产不产生异常,finally中的语句一定会执行 * 关闭资源 * } * * catch 异常的时候,要先 catch 具体的(小的)异常,然后再 catch 抽象的(大的)异常 */ try { System.out.println(2 / 0); } catch (ArithmeticException e) { System.out.println("系统正在维护中,请稍后,请与管理员联系,谢谢"); e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0300/Chapter0301TestEx.java ================================================ package com.basic.chapter0300; import java.io.*; /** * 异常处理 * * @author MarkShen * @since 20191121 */ public class Chapter0301TestEx { public static void main(String[] args) { try { new Chapter0301TestEx().f2(); } catch (IOException e) { e.printStackTrace(); } /* int[] arr = {1, 2, 3}; System.out.println(arr[2]); try { System.out.println(2/0); } catch (ArithmeticException e) { e.printStackTrace(); } */ //TestEx te = new TestEx(); //te.m(0); /* try { new TestEx().m(0); } catch (ArithmeticException ae) { ae.printStackTrace(); } */ FileInputStream in = null; try { in = new FileInputStream("myfile.txt"); int b; b = in.read(); while (b != -1) { System.out.print((char) b); b = in.read(); } } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } void m(int i) throws ArithmeticException { if (i == 0) throw new ArithmeticException("参数为0异常..."); } void f() throws FileNotFoundException, IOException { FileInputStream in = new FileInputStream("myfile.txt"); int b; b = in.read(); while (b != -1) { System.out.print((char) b); b = in.read(); } } void f2() throws IOException { /* try { f(); } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } catch (IOException e) { e.printStackTrace(); } */ f(); } } ================================================ FILE: src/main/java/com/basic/chapter0300/Chapter0302MethodException.java ================================================ package com.basic.chapter0300; /** * 方法异常 * * @author MarkShen * @since 20191121 */ public class Chapter0302MethodException { public static void main(String[] args) { crunch(null); } static void crunch(int[] a) { mash(a); } static void mash(int[] b) { System.out.println(b[0]); } } ================================================ FILE: src/main/java/com/basic/chapter0300/Chapter0303Junk.java ================================================ package com.basic.chapter0300; /** * Method Exception handle * 能处理的一定要处理,处理不了的往外抛 * 多读设计精巧的源码,体会设计思想尤为重要 * * 异常和继承之间的关系 * 重写方法需要抛出与原方法所抛出异常类型一致异常或不抛出异常。 * * @author MarkShen * @since 20191121 */ public class Chapter0303Junk { public static void main(String args[]) { try { a(); } catch (HighLevelException e) { e.printStackTrace(); } } static void a() throws HighLevelException { try { b(); } catch (MidLevelException e) { throw new HighLevelException(e); } } static void b() throws MidLevelException { c(); } static void c() throws MidLevelException { try { d(); } catch (LowLevelException e) { throw new MidLevelException(e); } } static void d() throws LowLevelException { e(); } static void e() throws LowLevelException { throw new LowLevelException(); } } /** * 使用自定义异常一般有如下步骤: * 1. 通过继承 java.lang.Exception类声明自己的异常类 * 2. 在方法适当的位置生成自定义异常的实例,并用throw抛出 * 3. 方法级使用 throws 语句声明该方法可能抛出的异常 */ class HighLevelException extends Exception { HighLevelException(Throwable cause) { super(cause); } } class MidLevelException extends Exception { MidLevelException(Throwable cause) { super(cause); } } class LowLevelException extends Exception { } ================================================ FILE: src/main/java/com/basic/chapter0400/Chapter0401ArrayIntroduction.java ================================================ package com.basic.chapter0400; /** * 数组[空间]介绍 * 一维数组声明方式 * type var[] 或者 type[] var * Java语言声明数组时不能指定其长度。 * int[5] a; // 非法,但是c或c++语言是可以的,分配在占内存空间上 * 元素为引用类型的数据中的每个元素都需要实例化 * * 用数组模拟算法 * 算法的演进 * 数组的内存的布局 * * @author MarkShen * @since 20191122 */ public class Chapter0401ArrayIntroduction { public static void main(String[] args) { // 第一种:静态初始化 int[] a = {1, 3, 5, 7, 9}; for (int temp : a) { System.out.println(temp); } // 第二种:动态初始化 int[] arr; arr = new int[5]; // 给数组元素赋值 for (int i = 0; i < 5; i++) { arr[i] = i; } // 变量数组元素 for (int j : arr) { System.out.println(j); } // 二位数组静态初始化 int[][] arrA = {{1, 3}, {1, 2, 4, 5}, {2, 4, 6}}; // int[3][2] arrB = {{1, 2}, {2, 3}, {4, 5}}; // 二维数组赋值 int[][] test = new int[3][]; int[][] array = new int[3][3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { array[i][j] = 0; } } // 二位数组遍历 System.out.println("二位数组的长度=" + array.length); for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { System.out.println(array[i][j]); } } } } ================================================ FILE: src/main/java/com/basic/chapter0400/Chapter0402TestArgs.java ================================================ package com.basic.chapter0400; public class Chapter0402TestArgs { public static void main(String[] args) { /* for(int i=0; i arr[j]) { int tmp = 0; tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } return arr; } /** * 选择排序算法 * * @param arr * @return */ private static double[] selectionSort(double[] arr) { if (arr == null) { return new double[0]; } double len = arr.length; int minIndex; double temp; for (int i = 0; i < len - 1; i++) { minIndex = i; for (int j = i + 1; j < len; j++) { if (arr[j] < arr[minIndex]) { // 寻找最小的数 minIndex = j; // 将最小数的索引保存 } } if (minIndex != i) { temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } return arr; } } ================================================ FILE: src/main/java/com/basic/chapter0400/Chapter0404TestDateSort.java ================================================ package com.basic.chapter0400; /** * 对对象进行排序 * * @author MarkShen * @since 20191124 */ public class Chapter0404TestDateSort { public static void main(String[] args) { Date[] days = new Date[5]; days[0] = new Date(2006, 5, 4); days[1] = new Date(2006, 7, 4); days[2] = new Date(2008, 5, 4); days[3] = new Date(2004, 5, 9); days[4] = new Date(2004, 5, 4); Date d = new Date(2006, 7, 4); String str = String.valueOf(d); // str = d.toString(); bubbleSort(days); for (int i = 0; i < days.length; i++) { System.out.println(days[i]); } System.out.println(binarySearch(days, d)); } public static Date[] bubbleSort(Date[] a) { int len = a.length; for (int i = len - 1; i >= 1; i--) { for (int j = 0; j <= i - 1; j++) { if (a[j].compare(a[j + 1]) > 0) { Date temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } return a; } public static int binarySearch(Date[] days, Date d) { if (days.length == 0) return -1; int startPos = 0; int endPos = days.length - 1; int m = (startPos + endPos) / 2; while (startPos <= endPos) { if (d.compare(days[m]) == 0) return m; if (d.compare(days[m]) > 0) { startPos = m + 1; } if (d.compare(days[m]) < 0) { endPos = m - 1; } m = (startPos + endPos) / 2; } return -1; } } class Date { int year, month, day; Date(int y, int m, int d) { year = y; month = m; day = d; } public int compare(Date date) { return year > date.year ? 1 : year < date.year ? -1 : month > date.month ? 1 : month < date.month ? -1 : day > date.day ? 1 : day < date.day ? -1 : 0; } public String toString() { return "Year:Month:Day -- " + year + "-" + month + "-" + day; } } ================================================ FILE: src/main/java/com/basic/chapter0400/Chapter0405TestSearch.java ================================================ package com.basic.chapter0400; /** * 搜索算法建立在排序算法的基础之上 * 二分法查找算法 * * @author MarkShen * @since 20191124 */ public class Chapter0405TestSearch { public static void main(String[] args) { int a[] = {1, 3, 6, 8, 9, 10, 12, 18, 20, 34}; int i = 12; //System.out.println(search(a, i)); System.out.println(binarySearch(a, i)); } public static int search(int[] a, int num) { for (int i = 0; i < a.length; i++) { if (a[i] == num) return i; } return -1; } public static int binarySearch(int[] a, int num) { if (a.length == 0) return -1; int startPos = 0; int endPos = a.length - 1; int m = (startPos + endPos) / 2; while (startPos <= endPos) { if (num == a[m]) return m; if (num > a[m]) { startPos = m + 1; } if (num < a[m]) { endPos = m - 1; } m = (startPos + endPos) / 2; } return -1; } } ================================================ FILE: src/main/java/com/basic/chapter0400/Chapter0406TestArrayCopy.java ================================================ package com.basic.chapter0400; public class Chapter0406TestArrayCopy { public static void main(String args[]) { String[] s = {"Mircosoft", "IBM", "Sun", "Oracle", "Apple"}; String[] sBak = new String[6]; System.arraycopy(s, 0, sBak, 0, s.length); for (int i = 0; i < sBak.length; i++) { System.out.print(sBak[i] + " "); } System.out.println(); int[][] intArray = {{1, 2}, {1, 2, 3}, {3, 4}}; int[][] intArrayBak = new int[3][]; System.arraycopy(intArray, 0, intArrayBak, 0, intArray.length); intArrayBak[2][1] = 100; for (int i = 0; i < intArray.length; i++) { for (int j = 0; j < intArray[i].length; j++) { System.out.print(intArray[i][j] + " "); } System.out.println(); } // Arrays 类中的数组的copyof方法 } } ================================================ FILE: src/main/java/com/basic/chapter0400/Count3Quit.java ================================================ package com.basic.chapter0400; /** * 数三退一 * * @author MarkShen * @since 20191124 */ public class Count3Quit { public static void main(String[] args) { boolean[] arr = new boolean[500]; for (int i = 0; i < arr.length; i++) { arr[i] = true; } int leftCount = arr.length; int countNum = 0; int index = 0; while (leftCount > 1) { if (arr[index] == true) { countNum++; if (countNum == 3) { countNum = 0; arr[index] = false; leftCount--; } } index++; if (index == arr.length) { index = 0; } } for (int i = 0; i < arr.length; i++) { if (arr[i] == true) { System.out.println(i); } } } } ================================================ FILE: src/main/java/com/basic/chapter0400/Count3Quit2.java ================================================ package com.basic.chapter0400; /** * 数三退一 * * @author MarkShen * @since 20191124 */ public class Count3Quit2 { public static void main(String[] args) { KidCircle kc = new KidCircle(500); int countNum = 0; Kid k = kc.first; while (kc.count > 1) { countNum++; if (countNum == 3) { countNum = 0; kc.delete(k); } k = k.right; } System.out.println(kc.first.id); } } class Kid { int id; Kid left; Kid right; } class KidCircle { int count = 0; Kid first, last; KidCircle(int n) { for (int i = 0; i < n; i++) { add(); } } void add() { Kid k = new Kid(); k.id = count; if (count <= 0) { first = k; last = k; k.left = k; k.right = k; } else { last.right = k; k.left = last; k.right = first; first.left = k; last = k; } count++; } void delete(Kid k) { if (count <= 0) { return; } else if (count == 1) { first = last = null; } else { k.left.right = k.right; k.right.left = k.left; if (k == first) { first = k.right; } else if (k == last) { last = k.left; } } count--; } } ================================================ FILE: src/main/java/com/basic/chapter0500/Chapter0501CommonUseClass.java ================================================ package com.basic.chapter0500; /** * 常用类介绍 * 字符串 * 基本类型包装类 * Math类 * File类 * 枚举类 */ public class Chapter0501CommonUseClass { public static void main(String[] args) { /** * */ String s1 = "hello"; String s2 = "world"; String s3 = "hello"; System.out.println(s1 == s3); String s4 = "he" + "llo"; System.out.println(s3 == s4); String s5 = new String("hello"); System.out.println(s3 == s5); System.out.println(s3.equals(s5)); String s6 = new String("he"); String s7 = s6 + "llo"; System.out.println(s3 == s7); } } ================================================ FILE: src/main/java/com/basic/chapter0500/Chapter0502TestString2.java ================================================ package com.basic.chapter0500; /** * String * * @author MarkShen * @since 20191127 */ public class Chapter0502TestString2 { public static void main(String[] args) { String s1 = "Sun java", s2 = "sun Java"; System.out.println(s1.charAt(1)); System.out.println(s2.length()); System.out.println(s1.indexOf("java")); System.out.println(s1.indexOf("Java")); System.out.println(s1.equals(s2)); System.out.println(s1.equalsIgnoreCase(s2)); String s3 = "我是程序员,我在学Java!"; System.out.println(s3.replace("我", "你")); } } ================================================ FILE: src/main/java/com/basic/chapter0500/Chapter0503TestString3.java ================================================ package com.basic.chapter0500; import java.util.Date; /** * String * * @author MarkShen * @since 20191127 */ public class Chapter0503TestString3 { public static void main(String[] args) { String s1 = "Welcome to Java world!"; System.out.println(s1.codePointAt(0)); System.out.println(s1.codePointBefore(1)); System.out.println(s1.codePointCount(0, 2)); System.out.println(s1.compareTo("Java world!")); System.out.println(s1.concat("+")); System.out.println(s1.contains("Java")); System.out.println(s1.contentEquals("Welcome to Java world!")); System.out.println(s1.toUpperCase()); System.out.println(s1.toLowerCase()); System.out.println(String.valueOf(3.14)); System.out.println(s1.trim()); System.out.println(s1.toCharArray().length); System.out.println(s1.substring(1)); System.out.println(s1.substring(0, 1)); System.out.println(s1.subSequence(0, 1)); System.out.println(s1.startsWith("Welcome")); System.out.println(s1.startsWith("Welcome", 5)); System.out.println(s1.split(" ").length); System.out.println("java.lang".split("\\.").length); Date d = new Date(); System.out.println(d); // 计算j是几位数 int j = 1234657; String num = String.valueOf(j); System.out.println("j是" + num.length() + "位数."); String s2 = "shen,jun,yu"; System.out.println(s2.split(",").length); String s3 = "asjljladjflAJSDLAJDSAJS,,,...,ASJDS"; System.out.println("大写字符数: " + countA2Z(s3)); System.out.println("小写字符数:" + counta2z(s3)); System.out.println("其它字符数:" + countOtherCharacter(s3)); System.out.println(s3.length()); } /** * 计算大写字符数量 * * @param string * @return */ private static int countA2Z(String string) { char[] chars = string.toCharArray(); int count = 0; for (char c : chars) { if ('A' <= c && c <= 'Z') { count ++; } } return count; } private static int countLowerCase(String string) { int count = 0; for (int i=0; i= 'a' && c <= 'z') { lCount ++; } else if (c >='A' && c <= 'Z') { uCount ++; } else { oCount ++; } } */ /* String sL = "abcdefghijklmnopqrstuvwxyz"; String sU = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for(int i=0; i * 原则:重写一个对象的 equals方法时,必须同时重写 hashCode方法 * 两个对象 equals,两个对象必须拥有相同的 hashcode. *

* 扩展:hashcode算法 * * @return */ public int hashCode() { return firstName.hashCode(); } public int compareTo(Object o) { Name n = (Name) o; int lastCmp = lastName.compareTo(n.lastName); return lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName); } } ================================================ FILE: src/main/java/com/basic/chapter0600/BasicGeneric.java ================================================ package com.basic.chapter0600; import java.util.*; /** * Java 泛型底层: * https://www.cnblogs.com/liang1101/p/6407871.html * * @author MarkShen * @since 20191221 */ public class BasicGeneric { public static void main(String[] args) { /** * 泛型起因: * JDK1.4以前类型不明确 * 装入集合的类型被当作Object被对待,从而失去自己实际的类型 * 从集合中取出时往往需要转型,效率低,容易产生错误 * 解决方法: * 在定义集合的时候,同时定义集合中元素的类型 * 可在定义Collection的时候指定 * 也可在循环时用Iterator指定 * * 好处: * 增强程序的可读性和稳定性 */ // 有序可以重复 List c = new ArrayList(); c.add("aaa"); c.add("bbb"); c.add("ccc"); for (int i = 0; i < c.size(); i++) { String s = c.get(i); System.out.println(s); } c.add(1, "insert"); System.out.println(); for (String s : c) { System.out.println(s); } Collection c2 = new HashSet(); c2.add("aaa"); c2.add("bbb"); c2.add("ccc"); for (Iterator it = c2.iterator(); it.hasNext(); ) { String s = it.next(); System.out.println(s); } } } class MyName implements Comparable { int age; public int compareTo(MyName mn) { if (this.age > mn.age) return 1; else if (this.age < mn.age) return -1; else return 0; } } ================================================ FILE: src/main/java/com/basic/chapter0600/CollectionsTest.java ================================================ package com.basic.chapter0600; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * 工具类测试 Collections * * @author MarkShen * @since 20191217 */ public class CollectionsTest { public static void main(String[] args) { List strs = new LinkedList<>(); for (int i = 0; i < 10; i++) { strs.add("a" + i); } System.out.println(strs); Collections.shuffle(strs); System.out.println(strs); Collections.reverse(strs); System.out.println(strs); Collections.sort(strs); System.out.println(strs); System.out.println(Collections.binarySearch(strs, "a5")); } } ================================================ FILE: src/main/java/com/basic/chapter0600/DataStructureSelection.java ================================================ package com.basic.chapter0600; /** * 数据结构选择 */ public class DataStructureSelection { public static void main(String[] args) { // 读快写慢 ArrayList 基于数组实现 // 写快读慢 LinkedList 基于链表实现 // 介于两者中间 Hash } } ================================================ FILE: src/main/java/com/basic/chapter0600/EnhancedFor.java ================================================ package com.basic.chapter0600; import java.util.*; public class EnhancedFor { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; for (int i : arr) { System.out.println(i); } Collection c = new ArrayList(); c.add(new String("aaa")); c.add(new String("bbb")); c.add(new String("ccc")); for (Object o : c) { System.out.println(o); } } } ================================================ FILE: src/main/java/com/basic/chapter0600/IteratorTest.java ================================================ package com.basic.chapter0600; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Iterator 测试 * * @author MarkShen * @since 20191210 */ public class IteratorTest { public static void main(String[] args) { // List 有序,可以重复 List list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); for (Iterator it = list.iterator(); it.hasNext(); ) { if ("d".equals(it.next())) { it.remove(); // list.remove("d"); // 会抛出 java.util.ConcurrentModificationException 异常 } } for (String str : list) { System.out.println(str); } } } ================================================ FILE: src/main/java/com/basic/chapter0600/SetTest.java ================================================ package com.basic.chapter0600; import java.util.HashSet; import java.util.Set; /** * Set:无序,不可重复 * * @author MarkShen * @since 20191210 */ public class SetTest { public static void main(String[] args) { Set set = new HashSet<>(); set.add("a"); set.add("a"); set.add("b"); for (String str : set) { System.out.println(str); } } } ================================================ FILE: src/main/java/com/basic/chapter0600/TestArgsWords.java ================================================ package com.basic.chapter0600; import java.util.*; /** * 参数中每个单词出现的次数 * auto-boxing * auto-unboxing * * @author MarkShen * @since 20191221 */ public class TestArgsWords { // private static final Integer ONE = new Integer(1); private static final int ONE = 1; public static void main(String args[]) { Map m = new HashMap(); for (int i = 0; i < args.length; i++) { //Integer freq = (Integer) m.get(args[i]); int freq = (Integer) m.get(args[i]) == null ? 0 : (Integer) m.get(args[i]); //m.put(args[i],(freq == null? ONE : new Integer(freq.intValue() + 1))); m.put(args[i], freq == 0 ? ONE : freq + 1); } System.out.println(m.size() + " distinct words detected:"); System.out.println(m); } } ================================================ FILE: src/main/java/com/basic/chapter0600/TestArgsWords2.java ================================================ package com.basic.chapter0600; import java.util.*; public class TestArgsWords2 { private static final int ONE = 1; public static void main(String args[]) { Map m = new HashMap(); for (int i = 0; i < args.length; i++) { if (!m.containsKey(args[i])) { m.put(args[i], ONE); } else { int freq = m.get(args[i]); m.put(args[i], freq + 1); } } System.out.println(m.size() + " distinct words detected:"); System.out.println(m); System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator> it = m.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } System.out.println("通过Map.entrySet遍历key和value"); for (Map.Entry entry : m.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } } } ================================================ FILE: src/main/java/com/basic/chapter0600/TestMap.java ================================================ package com.basic.chapter0600; import java.util.*; /** * key-value * Auto boxing unboxing * Java 自动打包,解包对性能的影响 * https://www.cnblogs.com/kakaku/articles/1320191.html * * @author MarkShen * @since 20191211 */ public class TestMap { public static void main(String args[]) { Map m1 = new HashMap(); Map m2 = new TreeMap(); //m1.put("one",new Integer(1)); m1.put("one", 1); //m1.put("two",new Integer(2)); m1.put("two", 2); //m1.put("three",new Integer(3)); m1.put("three", 3); //m2.put("A",new Integer(1)); m2.put("A", 1); //m2.put("B",new Integer(2)); m2.put("B", 2); System.out.println(m1.size()); System.out.println(m1.containsKey("one")); System.out.println //(m2.containsValue(new Integer(1))); (m2.containsValue(1)); if (m1.containsKey("two")) { //int i = ((Integer)m1.get("two")).intValue(); int i = (Integer) m1.get("two"); System.out.println(i); } Map m3 = new HashMap(m1); m3.putAll(m2); System.out.println(m3); } } ================================================ FILE: src/main/java/com/basic/chapter0600/TestMap2.java ================================================ package com.basic.chapter0600; import java.util.*; /** * 两个类如果equals,那么他们之间的hashcode必须一样 *

* 多读Map接口对应的API, JavaDoc */ public class TestMap2 { public static void main(String args[]) { Map m1 = new HashMap(); m1.put("one", 1); m1.put("two", 2); m1.put("three", 3); System.out.println(m1.size()); System.out.println(m1.containsKey("one")); if (m1.containsKey("two")) { // int i = ((Integer)m1.get("two")).intValue(); int i = m1.get("two"); System.out.println(i); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/FileCopy.java ================================================ package com.basic.chapter0700; import java.io.*; public class FileCopy { public static void main(String[] args) { int b = 0; FileReader in = null; FileWriter out = null; try { in = new FileReader("d:/share/java/HelloWorld.java"); out = new FileWriter("d:/share/java/io/HW.java"); while ((b = in.read()) != -1) { out.write(b); } out.close(); in.close(); } catch (FileNotFoundException e2) { e2.printStackTrace(); System.exit(-1); } catch (IOException e1) { e1.printStackTrace(); System.exit(-1); } System.out.println("success"); } } ================================================ FILE: src/main/java/com/basic/chapter0700/HelloWorld.java ================================================ package com.basic.chapter0700; /** * java.io.*; * io包裝的类 * 流的分类: * 方向(站在程序的角度):输入流,输出流 * 处理数据单位:字节(1 byte)流,字符(2 bytes)流 * 功能:节点流,处理流 *

* 一定要多差Java API * * @author MarkShen * @since 20191221 */ public class HelloWorld { static int j = 9; public static void main(String[] asdfasf) { System.out.println("HW"); System.out.println(123); System.out.println(j); int i = 8; } public static void m() { } } class TT { } ================================================ FILE: src/main/java/com/basic/chapter0700/TestBufferStream1.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestBufferStream1 { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("d:\\share\\java\\HelloWorld.java"); BufferedInputStream bis = new BufferedInputStream(fis); int c = 0; System.out.println(bis.read()); System.out.println(bis.read()); bis.mark(100); for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) { System.out.print((char) c + " "); } System.out.println(); bis.reset(); for (int i = 0; i <= 10 && (c = bis.read()) != -1; i++) { System.out.print((char) c + " "); } bis.close(); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestBufferStream2.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestBufferStream2 { public static void main(String[] args) { try { BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\share\\java\\dat2.txt")); BufferedReader br = new BufferedReader(new FileReader("d:\\share\\java\\dat2.txt")); String s = null; for (int i = 1; i <= 100; i++) { s = String.valueOf(Math.random()); bw.write(s); bw.newLine(); } bw.flush(); while ((s = br.readLine()) != null) { System.out.println(s); } bw.close(); br.close(); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestDataStream.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestDataStream { public static void main(String[] args) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); try { dos.writeDouble(Math.random()); dos.writeBoolean(true); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); System.out.println(bais.available()); DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readDouble()); System.out.println(dis.readBoolean()); dos.close(); dis.close(); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestFileInputStream.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestFileInputStream { public static void main(String[] args) { int b = 0; FileInputStream in = null; try { in = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java"); } catch (FileNotFoundException e) { System.out.println("找不到指定的文件"); System.exit(-1); } try { long num = 0; while ((b = in.read()) != -1) { System.out.print((char) b); num++; } in.close(); System.out.println(); System.out.println("共读取了 " + num + " 个字节"); } catch (IOException e1) { System.out.println("文件读取错误"); System.exit(-1); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestFileOutputStream.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestFileOutputStream { public static void main(String[] args) { int b = 0; FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("d:/share/java/HelloWorld.java"); out = new FileOutputStream("d:/share/java/io/HW.java"); while ((b = in.read()) != -1) { out.write(b); } in.close(); out.close(); } catch (FileNotFoundException e2) { System.out.println("找不到指定文件"); System.exit(-1); } catch (IOException e1) { System.out.println("文件复制错误"); System.exit(-1); } System.out.println("文件已复制"); } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestFileReader.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestFileReader { public static void main(String[] args) { FileReader fr = null; int c = 0; try { fr = new FileReader("d:\\share\\java\\io\\TestFileReader.java"); int ln = 0; while ((c = fr.read()) != -1) { //char ch = (char) fr.read(); System.out.print((char) c); //if (++ln >= 100) { System.out.println(); ln = 0;} } fr.close(); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); } catch (IOException e) { System.out.println("文件读取错误"); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestFileWriter.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestFileWriter { public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter("d:\\bak\\unicode.dat"); for (int c = 0; c <= 50000; c++) { fw.write(c); } fw.close(); } catch (IOException e1) { e1.printStackTrace(); System.out.println("文件写入错误"); System.exit(-1); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestFileWriter2.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestFileWriter2 { public static void main(String[] args) throws Exception { FileReader fr = new FileReader("d:/java/io/TestFileWriter2.java"); FileWriter fw = new FileWriter("d:/java/io/TestFileWriter2.bak"); int b; while ((b = fr.read()) != -1) { fw.write(b); } fr.close(); fw.close(); } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestObjectIO.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestObjectIO { public static void main(String args[]) throws Exception { T t = new T(); t.k = 8; FileOutputStream fos = new FileOutputStream("d:/share/java/io/testobjectio.dat"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(t); oos.flush(); oos.close(); FileInputStream fis = new FileInputStream("d:/share/java/io/testobjectio.dat"); ObjectInputStream ois = new ObjectInputStream(fis); T tReaded = (T) ois.readObject(); System.out.println(tReaded.i + " " + tReaded.j + " " + tReaded.d + " " + tReaded.k); } } class T implements Serializable { int i = 10; int j = 9; double d = 2.3; transient int k = 15; } ================================================ FILE: src/main/java/com/basic/chapter0700/TestPrintStream1.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestPrintStream1 { public static void main(String[] args) { PrintStream ps = null; try { FileOutputStream fos = new FileOutputStream("d:\\bak\\log.dat"); ps = new PrintStream(fos); } catch (IOException e) { e.printStackTrace(); } if (ps != null) { System.setOut(ps); } int ln = 0; for (char c = 0; c <= 60000; c++) { System.out.print(c + " "); if (ln++ >= 100) { System.out.println(); ln = 0; } } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestPrintStream2.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestPrintStream2 { public static void main(String[] args) { String filename = args[0]; if (filename != null) { list(filename, System.out); } } public static void list(String f, PrintStream fs) { try { BufferedReader br = new BufferedReader(new FileReader(f)); String s = null; while ((s = br.readLine()) != null) { fs.println(s); } br.close(); } catch (IOException e) { fs.println(e); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestPrintStream3.java ================================================ package com.basic.chapter0700; import java.util.*; import java.io.*; public class TestPrintStream3 { public static void main(String[] args) { String s = null; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { FileWriter fw = new FileWriter("d:\\bak\\logfile.log", true); //Log4J PrintWriter log = new PrintWriter(fw); while ((s = br.readLine()) != null) { if (s.equalsIgnoreCase("exit")) break; System.out.println(s.toUpperCase()); log.println("-----"); log.println(s.toUpperCase()); log.flush(); } log.println("===" + new Date() + "==="); log.flush(); log.close(); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestTransForm1.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestTransForm1 { public static void main(String[] args) { try { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt")); osw.write("mircosoftibmsunapplehp"); System.out.println(osw.getEncoding()); osw.close(); osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt", true), "ISO8859_1"); // latin-1 osw.write("mircosoftibmsunapplehp"); System.out.println(osw.getEncoding()); osw.close(); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0700/TestTransForm2.java ================================================ package com.basic.chapter0700; import java.io.*; public class TestTransForm2 { public static void main(String args[]) { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = null; try { s = br.readLine(); while (s != null) { if (s.equalsIgnoreCase("exit")) break; System.out.println(s.toUpperCase()); s = br.readLine(); } br.close(); } catch (IOException e) { e.printStackTrace(); } } } // 阻塞 ================================================ FILE: src/main/java/com/basic/chapter0700/TreeDir.java ================================================ package com.basic.chapter0700; import java.io.*; public class TreeDir { public static void main(String[] args) { listF(new File("d:/test"), 0); } public static void listF(File f, int level) { String preStr = ""; for (int i = 0; i < level; i++) preStr += " "; System.out.println(preStr + f.getName()); if (f.isDirectory()) { File[] files = f.listFiles(); for (File cf : files) listF(cf, level + 1); } } } ================================================ FILE: src/main/java/com/basic/chapter0800/111.txt ================================================ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ================================================ FILE: src/main/java/com/basic/chapter0800/ProducerConsumer.java ================================================ package com.basic.chapter0800; public class ProducerConsumer { public static void main(String[] args) { SyncStack ss = new SyncStack(); Producer p = new Producer(ss); Consumer c = new Consumer(ss); new Thread(p).start(); new Thread(p).start(); new Thread(p).start(); new Thread(c).start(); } } class WoTou { int id; WoTou(int id) { this.id = id; } public String toString() { return "WoTou : " + id; } } class SyncStack { int index = 0; WoTou[] arrWT = new WoTou[6]; public synchronized void push(WoTou wt) { while(index == arrWT.length) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); // 叫醒所有在该对象上的线程 arrWT[index] = wt; index ++; } public synchronized WoTou pop() { while(index == 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); index--; return arrWT[index]; } } class Producer implements Runnable { SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { WoTou wt = new WoTou(i); ss.push(wt); System.out.println("生产了:" + wt); try { Thread.sleep((int)(Math.random() * 200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { WoTou wt = ss.pop(); System.out.println("消费了: " + wt); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } } ================================================ FILE: src/main/java/com/basic/chapter0800/ProducerConsumer2.java ================================================ package com.basic.chapter0800; public class ProducerConsumer2 { public static void main(String args[]) { SyncStack2 stack = new SyncStack2(); Runnable p = new Producer2(stack); Runnable c = new Consumer2(stack); Thread t1 = new Thread(p); Thread t2 = new Thread(c); t1.start(); t2.start(); } } class SyncStack2 { private int index = 0; private char[] data = new char[6]; public synchronized void push(char c) { if (index == data.length) { try { this.wait(); } catch (InterruptedException e) { } } this.notify(); data[index] = c; index++; } public synchronized char pop() { if (index == 0) { try { this.wait(); } catch (InterruptedException e) { } } this.notify(); index--; return data[index]; } } class Producer2 implements Runnable { SyncStack2 stack; public Producer2(SyncStack2 s) { stack = s; } public void run() { for (int i = 0; i < 20; i++) { char c = (char) (Math.random() * 26 + 'A'); stack.push(c); System.out.println("produced: " + c); try { Thread.sleep((int) (Math.random() * 1000)); } catch (InterruptedException e) { } } } } class Consumer2 implements Runnable { SyncStack2 stack; public Consumer2(SyncStack2 s) { stack = s; } public void run() { for (int i = 0; i < 20; i++) { char c = stack.pop(); System.out.println("consumed: " + c); try { Thread.sleep((int) (Math.random() * 1000)); } catch (InterruptedException e) { } } } } ================================================ FILE: src/main/java/com/basic/chapter0800/RecursiveFile.java ================================================ package com.basic.chapter0800; public class RecursiveFile { public static void main(String[] args) { } public static void f() { } } ================================================ FILE: src/main/java/com/basic/chapter0800/T.java ================================================ package com.basic.chapter0800; public class T { public static void main(String[] args) { m1(); } public static void m1() { m2(); m3(); } public static void m2() { } public static void m3() { } } ================================================ FILE: src/main/java/com/basic/chapter0800/TT.java ================================================ package com.basic.chapter0800; public class TT implements Runnable { int b = 100; public synchronized void m1() throws Exception { //Thread.sleep(2000); b = 1000; Thread.sleep(5000); System.out.println("b = " + b); } public synchronized void m2() throws Exception { Thread.sleep(2500); b = 2000; } public void run() { try { m1(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { TT tt = new TT(); Thread t = new Thread(tt); t.start(); tt.m2(); System.out.println(tt.b); } } ================================================ FILE: src/main/java/com/basic/chapter0800/Test.java ================================================ package com.basic.chapter0800; import java.io.*; public class Test { public static void main(String[] args) throws Exception { FileWriter fw = new FileWriter("111.txt"); BufferedWriter bw = new BufferedWriter(fw); for (int i = 1; i <= 25; i++) { bw.write(i + " "); if (i % 5 == 0) bw.newLine(); } bw.flush(); bw.close(); } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestDeadLock.java ================================================ package com.basic.chapter0800; public class TestDeadLock implements Runnable { public int flag = 1; static Object o1 = new Object(), o2 = new Object(); public void run() { System.out.println("flag=" + flag); if(flag == 1) { synchronized(o1) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized(o2) { System.out.println("1"); } } } if(flag == 0) { synchronized(o2) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized(o1) { System.out.println("0"); } } } } public static void main(String[] args) { TestDeadLock td1 = new TestDeadLock(); TestDeadLock td2 = new TestDeadLock(); td1.flag = 1; td2.flag = 0; Thread t1 = new Thread(td1); Thread t2 = new Thread(td2); t1.start(); t2.start(); } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestInterrupt.java ================================================ package com.basic.chapter0800; import java.util.*; public class TestInterrupt { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); try { Thread.sleep(10000); } catch (InterruptedException e) { } thread.interrupt(); } } class MyThread extends Thread { boolean flag = true; public void run() { while (flag) { System.out.println("===" + new Date() + "==="); try { sleep(1000); } catch (InterruptedException e) { return; } } } } /* public void run() { while (true) { String temp = new Date().toString(); String t = temp.substring(11, temp.indexOf('C')); t = t.trim(); String[] time = t.split(":"); if (time.length == 3) { System.out.println(time[0] + time[1] + time[2]); } try { Thread.sleep(5000); } catch (InterruptedException e) { return; } } } } */ ================================================ FILE: src/main/java/com/basic/chapter0800/TestJoin.java ================================================ package com.basic.chapter0800; public class TestJoin { public static void main(String[] args) { MyThread2 t1 = new MyThread2("abcde"); t1.start(); try { t1.join(); } catch (InterruptedException e) { } for (int i = 1; i <= 10; i++) { System.out.println("i am main thread"); } } } class MyThread2 extends Thread { MyThread2(String s) { super(s); } public void run() { for (int i = 1; i <= 10; i++) { System.out.println("i am " + getName()); try { sleep(1000); } catch (InterruptedException e) { return; } } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestPriority.java ================================================ package com.basic.chapter0800; public class TestPriority { public static void main(String[] args) { Thread t1 = new Thread(new T1()); Thread t2 = new Thread(new T2()); t1.setPriority(Thread.NORM_PRIORITY + 3); t1.start(); t2.start(); } } class T1 implements Runnable { public void run() { for (int i = 0; i < 1000; i++) { System.out.println("T1: " + i); } } } class T2 implements Runnable { public void run() { for (int i = 0; i < 1000; i++) { System.out.println("------T2: " + i); } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestSync.java ================================================ package com.basic.chapter0800; public class TestSync implements Runnable { Timer timer = new Timer(); public static void main(String[] args) { TestSync test = new TestSync(); Thread t1 = new Thread(test); Thread t2 = new Thread(test); t1.setName("t1"); t2.setName("t2"); t1.start(); t2.start(); } public void run() { timer.add(Thread.currentThread().getName()); } } class Timer { private static int num = 0; public synchronized void add(String name) { // synchronized (this) { num++; try { Thread.sleep(1); } catch (InterruptedException e) { } System.out.println(name + ", " + num); // } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestThread1.java ================================================ package com.basic.chapter0800; public class TestThread1 { public static void main(String args[]) { Runner1 r = new Runner1(); r.start(); //r.run(); //Thread t = new Thread(r); //t.start(); for (int i = 0; i < 100; i++) { System.out.println("Main Thread:------" + i); } } } //class Runner1 implements Runnable { class Runner1 extends Thread { public void run() { for (int i = 0; i < 100; i++) { System.out.println("Runner1 :" + i); } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestThread2.java ================================================ package com.basic.chapter0800; public class TestThread2 { public static void main(String args[]) { Runner2 r = new Runner2(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); t1.start(); t2.start(); } } class Runner2 implements Runnable { public void run() { for (int i = 0; i < 30; i++) { System.out.println("No. " + i); } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestThread3.java ================================================ package com.basic.chapter0800; public class TestThread3 { public static void main(String args[]) { Runner3 r = new Runner3(); Thread t = new Thread(r); t.start(); } } class Runner3 implements Runnable { public void run() { for (int i = 0; i < 30; i++) { if (i % 10 == 0 && i != 0) { try { Thread.sleep(2000); } catch (InterruptedException e) { } } System.out.println("No. " + i); } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestThread4.java ================================================ package com.basic.chapter0800; public class TestThread4 { public static void main(String args[]) { Runner4 r = new Runner4(); Thread t = new Thread(r); t.start(); for (int i = 0; i < 100000; i++) { if (i % 10000 == 0 & i > 0) System.out.println("in thread main i=" + i); } System.out.println("Thread main is over"); r.shutDown(); //t.stop(); } } class Runner4 implements Runnable { private boolean flag = true; public void run() { int i = 0; while (flag == true) { System.out.print(" " + i++); } } public void shutDown() { flag = false; } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestThread5.java ================================================ package com.basic.chapter0800; public class TestThread5 { public static void main(String args[]){ Runner5 r = new Runner5(); Thread t = new Thread(r); t.start(); try{ t.join(); }catch(InterruptedException e){ } for(int i=0;i<50;i++){ System.out.println("main thread:" + i); } } } class Runner5 implements Runnable { public void run() { for(int i=0;i<50;i++) { System.out.println("SubThread: " + i); } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestThread6.java ================================================ package com.basic.chapter0800; public class TestThread6 { public static void main(String args[]) { Thread t = new Runner6(); t.start(); for (int i = 0; i < 50; i++) { System.out.println("MainThread: " + i); } } } class Runner6 extends Thread { public void run() { System.out.println(Thread.currentThread().isAlive()); for (int i = 0; i < 50; i++) { System.out.println("SubThread: " + i); } } } ================================================ FILE: src/main/java/com/basic/chapter0800/TestYield.java ================================================ package com.basic.chapter0800; public class TestYield { public static void main(String[] args) { MyThread3 t1 = new MyThread3("t1"); MyThread3 t2 = new MyThread3("t2"); t1.start(); t2.start(); } } class MyThread3 extends Thread { MyThread3(String s) { super(s); } public void run() { for (int i = 1; i <= 100; i++) { System.out.println(getName() + ": " + i); if (i % 10 == 0) { yield(); } } } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chapter0901TestUDPClient.java ================================================ package com.basic.chapter0900; import java.net.*; public class Chapter0901TestUDPClient { public static void main(String args[]) throws Exception { byte[] buf = "Hello".getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 5678)); DatagramSocket ds = new DatagramSocket(9999); ds.send(dp); ds.close(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chapter0901TestUDPServer.java ================================================ package com.basic.chapter0900; import java.net.*; public class Chapter0901TestUDPServer { public static void main(String args[]) throws Exception { byte buf[] = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); DatagramSocket ds = new DatagramSocket(5678); while (true) { ds.receive(dp); System.out.println(new String(buf, 0, dp.getLength())); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat03/ChatClient.java ================================================ package com.basic.chapter0900.Chat.Chat03; import java.io.*; import java.net.*; public class ChatClient { Socket s = null; public ChatClient() throws Exception { s = new Socket("127.0.0.1", 8888); } public void send(String str) throws Exception { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); } public void disconnect() throws Exception { s.close(); } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ChatClient cc = new ChatClient(); String str = br.readLine(); while (str != null && str.length() != 0) { cc.send(str); str = br.readLine(); } cc.disconnect(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat03/ChatServer.java ================================================ package com.basic.chapter0900.Chat.Chat03; import java.net.*; import java.util.*; import java.io.*; public class ChatServer { ServerSocket server = null; Collection cClient = new ArrayList(); public ChatServer(int port) throws Exception { server = new ServerSocket(port); } public void startServer() throws Exception { while (true) { Socket s = server.accept(); cClient.add(new ClientConn(s)); } } class ClientConn implements Runnable { Socket s = null; public ClientConn(Socket s) { this.s = s; (new Thread(this)).start(); } public void run() { try { DataInputStream dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); while (str != null && str.length() != 0) { System.out.println(str); str = dis.readUTF(); } s.close(); cClient.remove(this); } catch (IOException e) { System.out.println("client quit"); try { if (s != null) s.close(); cClient.remove(this); } catch (IOException ioe) { ioe.printStackTrace(); } } } } public static void main(String[] args) throws Exception { ChatServer cs = new ChatServer(8888); cs.startServer(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat05/ChatClient.java ================================================ package com.basic.chapter0900.Chat.Chat05; import java.io.*; import java.net.*; public class ChatClient { Socket s = null; public ChatClient() throws Exception { s = new Socket("127.0.0.1", 8888); (new Thread(new ReceiveThread())).start(); } public void send(String str) throws Exception { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); } public void disconnect() throws Exception { s.close(); } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ChatClient cc = new ChatClient(); String str = br.readLine(); while (str != null && str.length() != 0) { cc.send(str); str = br.readLine(); } cc.disconnect(); } class ReceiveThread implements Runnable { public void run() { if (s == null) return; try { DataInputStream dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); while (str != null && str.length() != 0) { System.out.println(str); str = dis.readUTF(); } } catch (Exception e) { e.printStackTrace(); } } } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat05/ChatServer.java ================================================ package com.basic.chapter0900.Chat.Chat05; import java.net.*; import java.util.*; import java.io.*; public class ChatServer { ServerSocket server = null; Collection cClient = new ArrayList(); public ChatServer(int port) throws Exception { server = new ServerSocket(port); } public void startServer() throws Exception { while (true) { Socket s = server.accept(); cClient.add(new ClientConn(s)); } } class ClientConn implements Runnable { Socket s = null; public ClientConn(Socket s) { this.s = s; (new Thread(this)).start(); } public void send(String str) throws IOException { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); } public void run() { try { DataInputStream dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); while (str != null && str.length() != 0) { System.out.println(str); for (Iterator it = cClient.iterator(); it.hasNext(); ) { ClientConn cc = (ClientConn) it.next(); if (this != cc) { cc.send(str); } } str = dis.readUTF(); //send(str); } s.close(); cClient.remove(this); } catch (IOException e) { System.out.println("client quit"); try { if (s != null) s.close(); cClient.remove(this); } catch (IOException ioe) { ioe.printStackTrace(); } } } } public static void main(String[] args) throws Exception { ChatServer cs = new ChatServer(8888); cs.startServer(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat07/ChatClient.java ================================================ package com.basic.chapter0900.Chat.Chat07; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; public class ChatClient extends Frame { TextArea ta = new TextArea(); TextField tf = new TextField(); public void launchFrame() throws Exception { this.add(ta, BorderLayout.CENTER); this.add(tf, BorderLayout.SOUTH); tf.addActionListener((ActionEvent ae) -> { try { String sSend = tf.getText(); if (sSend.trim().length() == 0) return; ChatClient.this.send(sSend); tf.setText(""); ta.append(sSend + "\n"); } catch (Exception e) { e.printStackTrace(); } }); setBounds(300, 300, 300, 400); setVisible(true); tf.requestFocus(); } Socket s = null; public ChatClient() throws Exception { s = new Socket("127.0.0.1", 8888); launchFrame(); (new Thread(new ReceiveThread())).start(); } public void send(String str) throws Exception { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); } public void disconnect() throws Exception { s.close(); } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ChatClient cc = new ChatClient(); String str = br.readLine(); while (str != null && str.length() != 0) { cc.send(str); str = br.readLine(); } cc.disconnect(); } class ReceiveThread implements Runnable { public void run() { if (s == null) return; try { DataInputStream dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); while (str != null && str.length() != 0) { // System.out.println(str); ChatClient.this.ta.append(str + "\n"); str = dis.readUTF(); } } catch (Exception e) { e.printStackTrace(); } } } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat07/ChatServer.java ================================================ package com.basic.chapter0900.Chat.Chat07; import java.net.*; import java.util.*; import java.io.*; public class ChatServer { ServerSocket server = null; Collection cClient = new ArrayList(); public ChatServer(int port) throws Exception { server = new ServerSocket(port); } public void startServer() throws Exception { while (true) { Socket s = server.accept(); cClient.add(new ClientConn(s)); } } class ClientConn implements Runnable { Socket s = null; public ClientConn(Socket s) { this.s = s; (new Thread(this)).start(); } public void send(String str) throws IOException { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); } public void run() { try { DataInputStream dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); while (str != null && str.length() != 0) { System.out.println(str); for (Iterator it = cClient.iterator(); it.hasNext(); ) { ClientConn cc = (ClientConn) it.next(); if (this != cc) { cc.send(str); } } str = dis.readUTF(); //send(str); } s.close(); cClient.remove(this); } catch (IOException e) { System.out.println("client quit"); try { if (s != null) s.close(); cClient.remove(this); } catch (IOException ioe) { ioe.printStackTrace(); } } } } public static void main(String[] args) throws Exception { ChatServer cs = new ChatServer(8888); cs.startServer(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat10/ChatClient.java ================================================ package com.basic.chapter0900.Chat.Chat10; import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; public class ChatClient extends Frame { TextArea ta = new TextArea(); TextField tf = new TextField(); public void launchFrame() throws Exception { this.add(ta, BorderLayout.CENTER); this.add(tf, BorderLayout.SOUTH); tf.addActionListener((ActionEvent ae) -> { try { String sSend = tf.getText(); if (sSend.trim().length() == 0) return; ChatClient.this.send(sSend); tf.setText(""); ta.append(sSend + "\n"); } catch (Exception e) { e.printStackTrace(); } }); this.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); setBounds(300, 300, 300, 400); setVisible(true); tf.requestFocus(); } Socket s = null; public ChatClient() throws Exception { s = new Socket("127.0.0.1", 8888); launchFrame(); (new Thread(new ReceiveThread())).start(); } public void send(String str) throws Exception { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); } public void disconnect() throws Exception { s.close(); } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ChatClient cc = new ChatClient(); String str = br.readLine(); while (str != null && str.length() != 0) { cc.send(str); str = br.readLine(); } cc.disconnect(); } class ReceiveThread implements Runnable { public void run() { if (s == null) return; try { DataInputStream dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); while (str != null && str.length() != 0) { //System.out.println(str); ChatClient.this.ta.append(str + "\n"); str = dis.readUTF(); } } catch (Exception e) { e.printStackTrace(); } } } } ================================================ FILE: src/main/java/com/basic/chapter0900/Chat/Chat10/ChatServer.java ================================================ package com.basic.chapter0900.Chat.Chat10; import java.net.*; import java.util.*; import java.io.*; import java.awt.*; import java.awt.event.*; public class ChatServer extends Frame { TextArea ta = new TextArea(); public void launchFrame() { add(ta, BorderLayout.CENTER); setBounds(0, 0, 200, 300); this.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); setVisible(true); } ServerSocket server = null; Collection cClient = new ArrayList(); public ChatServer(int port) throws Exception { server = new ServerSocket(port); launchFrame(); } public void startServer() throws Exception { while (true) { Socket s = server.accept(); cClient.add(new ClientConn(s)); ta.append("NEW-CLIENT " + s.getInetAddress() + ":" + s.getPort()); ta.append("\n" + "CLIENTS-COUNT: " + cClient.size() + "\n\n"); } } class ClientConn implements Runnable { Socket s = null; public ClientConn(Socket s) { this.s = s; (new Thread(this)).start(); } public void send(String str) throws IOException { DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeUTF(str); } public void dispose() { try { if (s != null) s.close(); cClient.remove(this); ta.append("A client out! \n"); ta.append("CLIENT-COUNT: " + cClient.size() + "\n\n"); } catch (Exception e) { e.printStackTrace(); } } public void run() { try { DataInputStream dis = new DataInputStream(s.getInputStream()); String str = dis.readUTF(); while (str != null && str.length() != 0) { System.out.println(str); for (Iterator it = cClient.iterator(); it.hasNext(); ) { ClientConn cc = (ClientConn) it.next(); if (this != cc) { cc.send(str); } } str = dis.readUTF(); //send(str); } this.dispose(); } catch (Exception e) { System.out.println("client quit"); this.dispose(); } } } public static void main(String[] args) throws Exception { ChatServer cs = new ChatServer(8888); cs.startServer(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/TCPClient.java ================================================ package com.basic.chapter0900; import java.net.*; import java.io.*; public class TCPClient { public static void main(String[] args) throws Exception { Socket s = new Socket("127.0.0.1", 6666); OutputStream os = s.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); Thread.sleep(30000); dos.writeUTF("hello server!"); dos.flush(); dos.close(); s.close(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/TCPServer.java ================================================ package com.basic.chapter0900; import java.net.*; import java.io.*; public class TCPServer { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(6666); while(true) { Socket s = ss.accept(); System.out.println("a client connect!"); DataInputStream dis = new DataInputStream(s.getInputStream()); System.out.println(dis.readUTF()); dis.close(); s.close(); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/TalkClient.java ================================================ package com.basic.chapter0900; import java.io.*; import java.net.*; public class TalkClient { public static void main(String args[]) { try { Socket socket = new Socket("127.0.0.1", 4700); BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); PrintWriter os = new PrintWriter(socket.getOutputStream()); BufferedReader is = new BufferedReader(new InputStreamReader( socket.getInputStream())); String readline; readline = sin.readLine(); while (!readline.equals("bye")) { os.println(readline); os.flush(); System.out.println("Client:" + readline); System.out.println("Server:" + is.readLine()); readline = sin.readLine(); } os.close(); is.close(); socket.close(); } catch (Exception e) { System.out.println("Error" + e); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/TalkServer.java ================================================ package com.basic.chapter0900; import java.io.*; import java.net.*; import java.applet.Applet; public class TalkServer { public static void main(String args[]) { try { ServerSocket server = null; try { server = new ServerSocket(4700); } catch (Exception e) { System.out.println("can not listen to:" + e); } Socket socket = null; try { socket = server.accept(); } catch (Exception e) { System.out.println("Error:" + e); } String line; BufferedReader is = new BufferedReader(new InputStreamReader( socket.getInputStream())); PrintWriter os = new PrintWriter(socket.getOutputStream()); BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Client:" + is.readLine()); line = sin.readLine(); while (!line.equals("bye")) { os.println(line); os.flush(); System.out.println("Server:" + line); System.out.println("Client:" + is.readLine()); line = sin.readLine(); } is.close(); os.close(); socket.close(); server.close(); } catch (Exception e) { System.out.println("Error" + e); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/TestClient.java ================================================ package com.basic.chapter0900; import java.net.*; import java.io.*; public class TestClient { public static void main(String args[]) { try { Socket s1 = new Socket("127.0.0.1", 8888); InputStream is = s1.getInputStream(); DataInputStream dis = new DataInputStream(is); System.out.println(dis.readUTF()); dis.close(); s1.close(); } catch (ConnectException connExc) { connExc.printStackTrace(); System.err.println("throw connection exception..."); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/TestServer.java ================================================ package com.basic.chapter0900; import java.net.*; import java.io.*; public class TestServer { public static void main(String args[]) { try { ServerSocket s = new ServerSocket(8888); while (true) { Socket s1 = s.accept(); OutputStream os = s1.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); dos.writeUTF("Hello," + s1.getInetAddress() + "port#" + s1.getPort() + " bye-bye!"); dos.close(); s1.close(); } } catch (IOException e) { e.printStackTrace(); System.out.println("异常信息:" + e); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/TestSockClient.java ================================================ package com.basic.chapter0900; import java.net.*; import java.io.*; public class TestSockClient { public static void main(String[] args) { InputStream is = null; OutputStream os = null; try { Socket socket = new Socket("localhost", 5888); is = socket.getInputStream(); os = socket.getOutputStream(); DataInputStream dis = new DataInputStream(is); DataOutputStream dos = new DataOutputStream(os); dos.writeUTF("hey"); String s = null; if ((s = dis.readUTF()) != null) ; System.out.println(s); dos.close(); dis.close(); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/TestSockServer.java ================================================ package com.basic.chapter0900; import java.io.*; import java.net.*; public class TestSockServer { public static void main(String[] args) { InputStream in = null; OutputStream out = null; try { ServerSocket ss = new ServerSocket(5888); Socket socket = ss.accept(); in = socket.getInputStream(); out = socket.getOutputStream(); DataOutputStream dos = new DataOutputStream(out); DataInputStream dis = new DataInputStream(in); String s = null; if ((s = dis.readUTF()) != null) { System.out.println(s); System.out.println("from: " + socket.getInetAddress()); System.out.println("Port: " + socket.getPort()); } dos.writeUTF("你好,世界!"); dis.close(); dos.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/TestUDPClient.java ================================================ package com.basic.chapter0900; import java.net.*; import java.io.*; public class TestUDPClient { public static void main(String args[]) throws Exception { long n = 10000L; ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeLong(n); byte[] buf = baos.toByteArray(); System.out.println(buf.length); DatagramPacket dp = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 5678) ); DatagramSocket ds = new DatagramSocket(9999); ds.send(dp); ds.close(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/TestUDPServer.java ================================================ package com.basic.chapter0900; import java.net.*; import java.io.*; public class TestUDPServer { public static void main(String args[]) throws Exception { byte buf[] = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); DatagramSocket ds = new DatagramSocket(5678); while (true) { ds.receive(dp); ByteArrayInputStream bais = new ByteArrayInputStream(buf); DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readLong()); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/zerocopy/traditonal/TraditionalClient.java ================================================ package com.basic.chapter0900.zerocopy.traditonal; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; public class TraditionalClient { public static void main(String[] args) { int port = 2000; String server = "localhost"; Socket socket = null; String lineToBeSent; DataOutputStream output = null; FileInputStream inputStream = null; int ERROR = 1; // connect to server try { socket = new Socket(server, port); System.out.println("Connected with server " + socket.getInetAddress() + ":" + socket.getPort()); } catch (UnknownHostException e) { System.out.println(e); System.exit(ERROR); } catch (IOException e) { System.out.println(e); System.exit(ERROR); } try { String fname = "D:\\soft\\julia-1.4.2-win64.exe"; inputStream = new FileInputStream(fname); output = new DataOutputStream(socket.getOutputStream()); long start = System.currentTimeMillis(); byte[] b = new byte[4096]; long read = 0, total = 0; while ((read = inputStream.read(b)) >= 0) { total = total + read; output.write(b); } System.out.println("bytes send--" + total + " and totaltime--" + (System.currentTimeMillis() - start)); } catch (IOException e) { System.out.println(e); } try { output.close(); socket.close(); inputStream.close(); } catch (IOException e) { System.out.println(e); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/zerocopy/traditonal/TraditionalServer.java ================================================ package com.basic.chapter0900.zerocopy.traditonal; import java.io.DataInputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class TraditionalServer { public static void main(String args[]) { int port = 2000; ServerSocket server_socket; DataInputStream input; try { server_socket = new ServerSocket(port); System.out.println("Server waiting for client on port " + server_socket.getLocalPort()); // server infinite loop while (true) { Socket socket = server_socket.accept(); System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort()); input = new DataInputStream(socket.getInputStream()); // print received data try { byte[] byteArray = new byte[4096]; while (true) { int nread = input.read(byteArray, 0, 4096); if (0 == nread) break; } } catch (IOException e) { System.out.println(e); } // connection closed by client try { socket.close(); System.out.println("Connection closed by client"); } catch (IOException e) { System.out.println(e); } } } catch (IOException e) { System.out.println(e); } } } ================================================ FILE: src/main/java/com/basic/chapter0900/zerocopy/transfer/TransferToClient.java ================================================ package com.basic.chapter0900.zerocopy.transfer; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.FileChannel; import java.nio.channels.SocketChannel; public class TransferToClient { public static void main(String[] args) throws IOException { TransferToClient sfc = new TransferToClient(); sfc.testSendfile(); } public void testSendfile() throws IOException { String host = "localhost"; int port = 9026; SocketAddress sad = new InetSocketAddress(host, port); SocketChannel sc = SocketChannel.open(); sc.connect(sad); sc.configureBlocking(true); String fname = "D:\\soft\\julia-1.4.2-win64.exe"; long fsize = 183678375L, sendzise = 4094; // FileProposerExample.stuffFile(fname, fsize); FileChannel fc = new FileInputStream(fname).getChannel(); long start = System.currentTimeMillis(); long nsent = 0, curnset = 0; curnset = fc.transferTo(0, fsize, sc); System.out.println( "total bytes transferred--" + curnset + " and time taken in MS--" + (System.currentTimeMillis() - start)); fc.close(); } } ================================================ FILE: src/main/java/com/basic/chapter0900/zerocopy/transfer/TransferToServer.java ================================================ package com.basic.chapter0900.zerocopy.transfer; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; public class TransferToServer { ServerSocketChannel listener = null; protected void mySetup() { InetSocketAddress listenAddr = new InetSocketAddress(9026); try { listener = ServerSocketChannel.open(); ServerSocket ss = listener.socket(); ss.setReuseAddress(true); ss.bind(listenAddr); System.out.println("Listening on port : " + listenAddr.toString()); } catch (IOException e) { System.out.println("Failed to bind, is port : " + listenAddr.toString() + " already in use ? Error Msg : " + e.getMessage()); e.printStackTrace(); } } public static void main(String[] args) { TransferToServer dns = new TransferToServer(); dns.mySetup(); dns.readData(); } private void readData() { ByteBuffer dst = ByteBuffer.allocate(4096); try { while (true) { SocketChannel conn = listener.accept(); System.out.println("Accepted : " + conn); conn.configureBlocking(true); int nread = 0; while (nread != -1) { try { nread = conn.read(dst); } catch (IOException e) { e.printStackTrace(); conn.socket().close(); nread = -1; } dst.rewind(); } } } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: src/main/java/com/basic/chapter1000/AWTDrawing.java ================================================ package com.basic.chapter1000; import java.awt.*; public class AWTDrawing { private Frame f = new Frame(" Hello Out There!"); private Panel p = new Panel(); public void launchFrame() { f.add(p); f.setSize( 170,170); f.setBackground( Color.blue); f.setVisible( true); p.setForeground(Color.red); Graphics g = p.getGraphics(); g.drawArc(30,40,50,60,70,80); g.fillArc(30,40,50,60,70,80); } public static void main( String args[]) { AWTDrawing guiWindow = new AWTDrawing(); guiWindow.launchFrame(); } } ================================================ FILE: src/main/java/com/basic/chapter1000/AWTDrawing2.java ================================================ package com.basic.chapter1000; import java.awt.*; class SubPanel extends Panel{ public void paint(Graphics g){ g.drawString("this is a drawing test!",20,20); g.drawLine(30,60,100,120); g.draw3DRect(60,50,70,30,false); } } public class AWTDrawing2 { private Frame f = new Frame(" Hello Out There!"); private SubPanel p = new SubPanel(); public void launchFrame() { f.add(p); f.setSize(170,170); f.setBackground( new Color(89,145,145)); f.setVisible( true); } public static void main( String args[]) { AWTDrawing2 guiWindow = new AWTDrawing2(); guiWindow.launchFrame(); } } ================================================ FILE: src/main/java/com/basic/chapter1000/CenterPanel.java ================================================ package com.basic.chapter1000; import java.awt.*; public class CenterPanel { public static void main(String args[]) { new MyFrame3(300, 300, 400, 300, Color.BLUE); } } class MyFrame3 extends Frame { private Panel p; MyFrame3(int x, int y, int w, int h, Color c) { super("FrameWithPanel"); setLayout(null); setBounds(x, y, w, h); setBackground(c); p = new Panel(null); p.setBounds(w / 4, h / 4, w / 2, h / 2); p.setBackground(Color.YELLOW); add(p); setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/MyMouseAdapter.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; import java.util.*; public class MyMouseAdapter { public static void main(String args[]) { new MyFrame("drawing..."); } } class MyFrame extends Frame { ArrayList points = null; MyFrame(String s) { super(s); points = new ArrayList(); setLayout(null); setBounds(300, 300, 400, 300); this.setBackground(new Color(204, 204, 255)); setVisible(true); this.addMouseListener(new Monitor()); } public void paint(Graphics g) { Iterator i = points.iterator(); while (i.hasNext()) { Point p = (Point) i.next(); g.setColor(Color.BLUE); g.fillOval(p.x, p.y, 10, 10); } } public void addPoint(Point p) { points.add(p); } } class Monitor extends MouseAdapter { public void mousePressed(MouseEvent e) { MyFrame f = (MyFrame) e.getSource(); f.addPoint(new Point(e.getX(), e.getY())); f.repaint(); } } ================================================ FILE: src/main/java/com/basic/chapter1000/MyMouseAdapterGeneric.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; import java.util.*; public class MyMouseAdapterGeneric { public static void main(String args[]) { new MyFrame992("drawing..."); } } class MyFrame992 extends Frame { ArrayList points = null; MyFrame992(String s) { super(s); points = new ArrayList(); setLayout(null); setBounds(300, 300, 400, 300); this.setBackground(new Color(204, 204, 255)); setVisible(true); this.addMouseListener(new Monitor2()); } public void paint(Graphics g) { Iterator i = points.iterator(); while (i.hasNext()) { Point p = i.next(); g.setColor(Color.BLUE); g.fillOval(p.x, p.y, 10, 10); } } public void addPoint(Point p) { points.add(p); } } class Monitor2 extends MouseAdapter { public void mousePressed(MouseEvent e) { MyFrame992 f = (MyFrame992) e.getSource(); f.addPoint(new Point(e.getX(), e.getY())); f.repaint(); } } ================================================ FILE: src/main/java/com/basic/chapter1000/NestedContainer.java ================================================ package com.basic.chapter1000; import java.awt.*; public class NestedContainer { public static void main(String args[]) { Frame f = new Frame("NestedContainer"); Button b0 = new Button("display Area"); Panel p = new Panel(); p.setLayout(new GridLayout(2, 2)); Button b1 = new Button("1"); Button b2 = new Button("2"); Button b3 = new Button("3"); Button b4 = new Button("4"); p.add(b1); p.add(b2); p.add(b3); p.add(b4); f.add(b0, "North"); f.add(p, "Center"); f.pack(); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TFActionEvent.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TFActionEvent { /** * @param args */ public static void main(String[] args) { new TFFrame(); } } class TFFrame extends Frame { TFFrame() { TextField tf = new TextField(); add(tf); tf.addActionListener(new TFActionListener()); pack(); setVisible(true); } } class TFActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { TextField tf = (TextField) e.getSource(); System.out.println(tf.getText()); //tf.setText(""); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TFMath.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TFMath { public static void main(String[] args) { new TFFrame3().launchFrame(); } } class TFFrame3 extends Frame { TextField num1, num2, num3; public void launchFrame() { num1 = new TextField(10); num2 = new TextField(10); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyMonitor()); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); } private class MyMonitor implements ActionListener { public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); num3.setText("" + (n1 + n2)); } } } //class MyMonitor implements ActionListener { //TextField num1, num2, num3; /* public MyMonitor(TextField num1, TextField num2, TextField num3) { this.num1 = num1; this.num2 = num2; this.num3 = num3; } */ /* TFFrame tf = null; public MyMonitor(TFFrame tf) { this.tf = tf; } public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(tf.num1.getText()); int n2 = Integer.parseInt(tf.num2.getText()); tf.num3.setText("" + (n1+n2)); } } */ ================================================ FILE: src/main/java/com/basic/chapter1000/TFMathTest.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TFMathTest extends Frame { TextField num1; TextField num2; TextField sum; /** * @param args */ public static void main(String[] args) { new TFMathTest().launchFrame(); } public void launchFrame() { num1 = new TextField(); num2 = new TextField(); sum = new TextField(); num1.setColumns(10); num2.setColumns(10); sum.setColumns(15); setLayout(new FlowLayout()); //setSize(500, 30); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyListener2(this)); add(num1); add(lblPlus); add(num2); add(btnEqual); add(sum); pack(); setVisible(true); } } class MyListener2 implements ActionListener { private TFMathTest tfmt; public MyListener2(TFMathTest tfmt) { this.tfmt = tfmt; } public void actionPerformed(ActionEvent e) { String s1 = tfmt.num1.getText(); String s2 = tfmt.num2.getText(); int i1 = Integer.parseInt(s1); int i2 = Integer.parseInt(s2); tfmt.sum.setText(String.valueOf(i1 + i2)); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TFMathTest2.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TFMathTest2 extends Frame { TextField num1; TextField num2; TextField sum; /** * @param args */ public static void main(String[] args) { new TFMathTest2().launchFrame(); } public void launchFrame() { num1 = new TextField(); num2 = new TextField(); sum = new TextField(); num1.setColumns(10); num2.setColumns(10); sum.setColumns(15); setLayout(new FlowLayout()); //setSize(500, 30); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyListener(this)); add(num1); add(lblPlus); add(num2); add(btnEqual); add(sum); pack(); setVisible(true); } } class MyListener implements ActionListener { //private TFMathTest2 tfmt; private TextField num1, num2, sum; public MyListener(TFMathTest2 tfmt) { //this.tfmt = tfmt; /* this.num1 = tfmt.num1; this.num2 = tfmt.num2; this.sum = tfmt.sum; */ this(tfmt.num1, tfmt.num2, tfmt.sum); } public MyListener(TextField num1, TextField num2, TextField sum) { this.num1 = num1; this.num2 = num2; this.sum = sum; } public void actionPerformed(ActionEvent e) { String s1 = num1.getText(); String s2 = num2.getText(); int i1 = Integer.parseInt(s1); int i2 = Integer.parseInt(s2); sum.setText(String.valueOf(i1 + i2)); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TFPassword.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TFPassword { /** * @param args */ public static void main(String[] args) { new TFFrame2(); } } class TFFrame2 extends Frame { TFFrame2() { TextField tf = new TextField(); add(tf); tf.addActionListener(new TFActionListener2()); tf.setEchoChar('*'); pack(); setVisible(true); } } class TFActionListener2 implements ActionListener { public void actionPerformed(ActionEvent e) { TextField tf = (TextField) e.getSource(); System.out.println(tf.getText()); tf.setText(""); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TenButtons.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TenButtons { public static void main(String args[]) { Frame f = new Frame("Java Frame"); f.setLayout(new GridLayout(2, 1)); f.setLocation(300, 400); f.setSize(300, 200); f.setBackground(new Color(204, 204, 255)); Panel p1 = new Panel(new BorderLayout()); Panel p2 = new Panel(new BorderLayout()); Panel p11 = new Panel(new GridLayout(2, 1)); Panel p21 = new Panel(new GridLayout(2, 2)); p1.add(new Button("BUTTON"), BorderLayout.WEST); p1.add(new Button("BUTTON"), BorderLayout.EAST); p11.add(new Button("BUTTON")); p11.add(new Button("BUTTON")); p1.add(p11, BorderLayout.CENTER); p2.add(new Button("BUTTON"), BorderLayout.WEST); p2.add(new Button("BUTTON"), BorderLayout.EAST); for (int i = 1; i <= 4; i++) { p21.add(new Button("BUTTON")); } p2.add(p21, BorderLayout.CENTER); f.add(p1); f.add(p2); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/Test.java ================================================ package com.basic.chapter1000; import java.awt.*; public class Test { public static void main(String args[]) { Frame f = new Frame("Java Gui"); f.setLayout(null); Button b = new Button("Button1"); f.add(b); b.setLocation(47, 70); b.setSize(60, 25); f.setSize(150, 150); f.setBackground(new Color(90, 145, 145, 200)); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestActionEvent.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TestActionEvent { public static void main(String args[]) { Frame f = new Frame("Test"); Button b = new Button("Press Me!"); Monitor3 bh = new Monitor3(); b.addActionListener(bh); f.add(b, BorderLayout.CENTER); f.pack(); f.setVisible(true); } } class Monitor3 implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("a button has been pressed"); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestActionEvent2.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TestActionEvent2 { public static void main(String args[]) { Frame f = new Frame("Test"); Button b1 = new Button("Start"); Button b2 = new Button("Stop"); Monitor6 bh = new Monitor6(); b1.addActionListener(bh); b2.addActionListener(bh); b2.setActionCommand("game over"); f.add(b1, "North"); f.add(b2, "Center"); f.pack(); f.setVisible(true); } } class Monitor6 implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("a button has been pressed," + "the relative info is:\n " + e.getActionCommand()); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestAnonymous.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TestAnonymous { Frame f = new Frame("Test Anonymous"); TextField tf = new TextField(30); public TestAnonymous() { f.add(new Label("Mouse"), "North"); f.add(tf, "South"); f.addMouseMotionListener( new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { String s = "(" + e.getX() + "," + e.getY() + ")"; tf.setText(s); } public void mouseMoved(MouseEvent e) { } } ); f.setSize(300, 200); f.setVisible(true); } public static void main(String args[]) { TestAnonymous t = new TestAnonymous(); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestAnonymous2.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TestAnonymous2 { Frame f = new Frame("Test"); TextField tf = new TextField(10); Button b1 = new Button("Start"); public TestAnonymous2() { f.add(b1, "North"); f.add(tf, "South"); b1.addActionListener(new ActionListener() { private int i; public void actionPerformed(ActionEvent e) { tf.setText(e.getActionCommand() + ++i); } }); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.pack(); f.setVisible(true); } public static void main(String args[]) { new TestAnonymous2(); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestBorderLayout.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestBorderLayout { public static void main(String args[]) { Frame f; f = new Frame("Border Layout"); Button bn = new Button("BN"); Button bs = new Button("BS"); Button bw = new Button("BW"); Button be = new Button("BE"); Button bc = new Button("BC"); f.add(bn, "North"); f.add(bs, "South"); f.add(bw, "West"); f.add(be, "East"); f.add(bc, "Center"); /* f.add(bn, BorderLayout.NORTH); f.add(bs, BorderLayout.SOUTH); f.add(bw, BorderLayout.WEST); f.add(be, BorderLayout.EAST); f.add(bc, BorderLayout.CENTER); */ f.setSize(200, 200); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestFlowLayout.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestFlowLayout { public static void main(String args[]) { Frame f = new Frame("Flow Layout"); Button button1 = new Button("Ok"); Button button2 = new Button("Open"); Button button3 = new Button("Close"); f.setLayout(new FlowLayout(FlowLayout.LEFT)); f.add(button1); f.add(button2); f.add(button3); f.setSize(100, 100); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestFlowLayout2.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestFlowLayout2 { public static void main(String args[]) { Frame f = new Frame("Java Frame"); FlowLayout l = new FlowLayout(FlowLayout.CENTER, 20, 40); f.setLayout(l); f.setLocation(300, 400); f.setSize(300, 200); f.setBackground(new Color(204, 204, 255)); for (int i = 1; i <= 7; i++) { f.add(new Button("BUTTON")); } f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestFrame.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestFrame { public static void main( String args[]) { Frame f = new Frame("My First Test"); f.setLocation(300, 300); f.setSize( 170,100); f.setBackground( Color.blue); f.setResizable(false); f.setVisible( true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestFrameWithPanel.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestFrameWithPanel { public static void main(String args[]) { Frame f = new Frame("MyTest Frame"); Panel pan = new Panel(); f.setSize(200, 200); f.setBackground(Color.blue); f.setLayout(null); pan.setSize(100, 100); pan.setBackground(Color.green); f.add(pan); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestGridLayout.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestGridLayout { public static void main(String args[]) { Frame f = new Frame("GridLayout Example"); Button b1 = new Button("b1"); Button b2 = new Button("b2"); Button b3 = new Button("b3"); Button b4 = new Button("b4"); Button b5 = new Button("b5"); Button b6 = new Button("b6"); f.setLayout(new GridLayout(3, 2)); f.add(b1); f.add(b2); f.add(b3); f.add(b4); f.add(b5); f.add(b6); f.pack(); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestInner.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TestInner { Frame f = new Frame("Mouse"); TextField tf = new TextField(30); public TestInner() { f.add(new Label("Mouse"), "North"); f.add(tf, "South"); f.setBackground(new Color(120, 175, 175)); f.addMouseMotionListener(new InnerMonitor()); f.addMouseListener(new InnerMonitor()); f.setSize(300, 200); f.setVisible(true); } public static void main(String args[]) { TestInner t = new TestInner(); } private class InnerMonitor implements MouseMotionListener, MouseListener { public void mouseDragged(MouseEvent e) { String s = "(" + e.getX() + "," + e.getY() + ")"; tf.setText(s); } public void mouseEntered(MouseEvent e) { String s = "Start"; tf.setText(s); } public void mouseExited(MouseEvent e) { String s = "end"; tf.setText(s); } public void mouseMoved(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } }//end of Inner class }//end of Outer class ================================================ FILE: src/main/java/com/basic/chapter1000/TestKey.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TestKey { public static void main(String[] args) { new KeyFrame().launchFrame(); } } class KeyFrame extends Frame { public void launchFrame() { setSize(200, 200); setLocation(300, 300); addKeyListener(new MyKeyMonitor()); setVisible(true); } class MyKeyMonitor extends KeyAdapter { public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_UP) { System.out.println("UP"); } } } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestMouseMotion.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; import java.util.*; public class TestMouseMotion { public static void main(String args[]) { new MyFrame88("drawing..."); } } class MyFrame88 extends Frame { ArrayList points = null; MyFrame88(String s) { super(s); points = new ArrayList(); setLayout(null); setBounds(300, 300, 400, 300); this.setBackground(new Color(204, 204, 255)); setVisible(true); this.addMouseMotionListener(new Monitor5()); } public void paint(Graphics g) { Iterator i = points.iterator(); while (i.hasNext()) { Point p = (Point) i.next(); g.setColor(Color.BLUE); g.fillOval(p.x, p.y, 10, 10); } } public void addPoint(Point p) { points.add(p); } } class Monitor5 extends MouseMotionAdapter { private int num = 0; public void mouseMoved(MouseEvent e) { MyFrame88 f = (MyFrame88) e.getSource(); f.addPoint(new Point(e.getX(), e.getY())); if (num++ >= 5) { f.repaint(); num = 0; } } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestMouseMotionGeneric.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; import java.util.*; public class TestMouseMotionGeneric { public static void main(String args[]) { new MyFrame888("drawing..."); } } class MyFrame888 extends Frame { ArrayList points = null; MyFrame888(String s) { super(s); points = new ArrayList(); setLayout(null); setBounds(300, 300, 400, 300); this.setBackground(new Color(204, 204, 255)); setVisible(true); this.addMouseMotionListener(new Monitor4()); } public void paint(Graphics g) { Iterator i = points.iterator(); while (i.hasNext()) { Point p = i.next(); g.setColor(Color.BLUE); g.fillOval(p.x, p.y, 10, 10); } } public void addPoint(Point p) { points.add(p); } } class Monitor4 extends MouseMotionAdapter { private int num = 0; public void mouseMoved(MouseEvent e) { MyFrame888 f = (MyFrame888) e.getSource(); f.addPoint(new Point(e.getX(), e.getY())); if (num++ >= 5) { f.repaint(); num = 0; } } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestMultiFrame.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestMultiFrame { public static void main(String args[]) { MyFrame4 f1 = new MyFrame4(100, 100, 200, 200, Color.BLUE); MyFrame4 f2 = new MyFrame4(300, 100, 200, 200, Color.YELLOW); MyFrame4 f3 = new MyFrame4(100, 300, 200, 200, Color.GREEN); MyFrame4 f4 = new MyFrame4(300, 300, 200, 200, Color.MAGENTA); } } class MyFrame4 extends Frame { static int id = 0; MyFrame4(int x, int y, int w, int h, Color color) { super("MyFrame4 " + (++id)); setBackground(color); setLayout(null); setBounds(x, y, w, h); setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestMultiPanel.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestMultiPanel { public static void main(String args[]) { new MyFrame2("MyFrameWithPanel", 300, 300, 400, 300); } } class MyFrame2 extends Frame { private Panel p1, p2, p3, p4; MyFrame2(String s, int x, int y, int w, int h) { super(s); setLayout(null); p1 = new Panel(null); p2 = new Panel(null); p3 = new Panel(null); p4 = new Panel(null); p1.setBounds(0, 0, w / 2, h / 2); p2.setBounds(0, h / 2, w / 2, h / 2); p3.setBounds(w / 2, 0, w / 2, h / 2); p4.setBounds(w / 2, h / 2, w / 2, h / 2); p1.setBackground(Color.BLUE); p2.setBackground(Color.GREEN); p3.setBackground(Color.YELLOW); p4.setBackground(Color.MAGENTA); add(p1); add(p2); add(p3); add(p4); setBounds(x, y, w, h); setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestPaint.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestPaint { public static void main(String[] args) { new PaintFrame().launchFrame(); } } class PaintFrame extends Frame { public void launchFrame() { setBounds(200, 200, 640, 480); setVisible(true); } public void paint(Graphics g) { Color c = g.getColor(); g.setColor(Color.red); g.fillOval(50, 50, 30, 30); g.setColor(Color.green); g.fillRect(80, 80, 40, 40); g.setColor(c); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestPanel.java ================================================ package com.basic.chapter1000; import java.awt.*; public class TestPanel { public static void main(String args[]) { Frame f = new Frame("Java Frame with Panel"); Panel p = new Panel(null); f.setLayout(null); f.setBounds(300, 300, 500, 500); f.setBackground(new Color(0, 0, 102)); p.setBounds(50, 50, 400, 400); p.setBackground(new Color(204, 204, 255)); f.add(p); f.setVisible(true); } } ================================================ FILE: src/main/java/com/basic/chapter1000/TestWindowClose.java ================================================ package com.basic.chapter1000; import java.awt.*; import java.awt.event.*; public class TestWindowClose { public static void main(String args[]) { new MyFrame55("MyFrame"); } } class MyFrame55 extends Frame { MyFrame55(String s) { super(s); setLayout(null); setBounds(300, 300, 400, 300); this.setBackground(new Color(204, 204, 255)); setVisible(true); //this.addWindowListener(new MyWindowMonitor()); this.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { setVisible(false); System.exit(-1); } }); } /* class MyWindowMonitor extends WindowAdapter { public void windowClosing(WindowEvent e) { setVisible(false); System.exit(0); } } */ } ================================================ FILE: src/main/java/com/basic/chapter1100/TestReflect.java ================================================ package com.basic.chapter1100; import java.lang.reflect.*; /** * 反射 * * @author MarkShen * @since 20191130 */ public class TestReflect { public static void main(String[] args) throws Exception { //m1(); //m2(); //m3("java.lang.Thread"); //m4(); //m5(); //m6(); //String s = "java.lang.String"; //从文件里读出来的 //new s() //m7(); //m8(); //m9(); m10(); } private static void m1() { String s = new String(); Class c = s.getClass(); System.out.println(c); Class su = c.getSuperclass(); System.out.println(su); System.out.println(su.getSuperclass()); } private static void m2() { Class c = String.class; System.out.println(c); } private static void m3(String className) { try { Class.forName(className); } catch (ClassNotFoundException e) { System.out.println("this class doesn't exist!"); } } private static void m4() { int m = String.class.getModifiers(); System.out.println(Modifier.isPublic(m)); System.out.println(Modifier.isFinal(m)); System.out.println(Modifier.isStatic(m)); } private static void m5() { for(Class c : String.class.getInterfaces()) { System.out.println(c); } System.out.println(java.lang.Comparable.class.isInterface()); } private static void m6() { Field[] fs = System.class.getFields(); for(Field f : fs) { System.out.println(f); } } private static void m7() throws Exception { Constructor[] cs = String.class.getConstructors(); for(Constructor c : cs) { System.out.println(c); for(Class paraClass : c.getParameterTypes()) { System.out.print(paraClass + " "); } System.out.println(); } String.class.newInstance(); } private static void m8() throws Exception { Class[] argClasses = new Class[] {int.class, int.class}; Object[] args = new Object[] {new Integer(12), new Integer(24)}; Constructor c = java.awt.Point.class.getConstructor(argClasses); Object o = c.newInstance(args); System.out.println(o); } private static void m9() throws Exception { Class[] argClasses = new Class[] {String.class}; Object[] args = new Object[] {new String("world!")}; Method m = java.lang.String.class.getMethod("concat", argClasses); String result = (String)m.invoke(new String("hello"), args); System.out.println(result); } private static void m10() throws Exception { /* Class cls = Class.forName("java.lang.String"); Object arr = Array.newInstance(cls, 10); Array.set(arr, 5, "this is a test"); String s = (String)Array.get(arr, 5); System.out.println(s); */ //例中创建了一个 5 x 10 x 15 的整型数组,并为处于 [3][5][10] 的元素赋了值为 37。 //注意,多维数组实际上就是数组的数组,例如,第一个 Array.get 之后, //arrobj 是一个 10 x 15 的数组。进而取得其中的一个元素,即长度为 15 的数组, //并使用 Array.setInt 为它的第 10 个元素赋值。 int dims[] = new int[]{5, 10, 15}; Object arr = Array.newInstance(Integer.TYPE, dims); Object arrobj = Array.get(arr, 3); Class cls = arrobj.getClass().getComponentType(); System.out.println(cls); arrobj = Array.get(arrobj, 5); Array.setInt(arrobj, 10, 37); int arrcast[][][] = (int[][][]) arr; System.out.println(arrcast[3][5][10]); } } ================================================ FILE: src/main/java/com/basic/chapter1200/QQClient.java ================================================ package com.basic.chapter1200; public class QQClient { } ================================================ FILE: src/main/java/com/basic/chapter1200/QQServer.java ================================================ package com.basic.chapter1200; public class QQServer { } ================================================ FILE: src/main/java/com/geo/GeoLite2-City.mmdb ================================================ [File too large to display: 58.4 MB] ================================================ FILE: src/main/java/com/geo/GeoTest.java ================================================ package com.geo; import com.maxmind.geoip2.DatabaseReader; import com.maxmind.geoip2.model.CityResponse; import com.maxmind.geoip2.record.*; import java.io.File; import java.net.InetAddress; /** * 根据ip地址获取ip地址所在地 * https://github.com/maxmind/GeoIP2-java * * @author MarkShen * @since 20191204 */ public class GeoTest { static String IP = "182.61.200.6"; /** * 指定数据库路径 */ static String DATABASE_PATH = System.getProperty("user.dir") + "/src/main/java/com/geo/GeoLite2-City.mmdb"; public static void main(String[] args) throws Exception { // A File object pointing to your GeoIP2 or GeoLite2 database File database = new File(DATABASE_PATH); // This creates the DatabaseReader object. To improve performance, reuse // the object across lookups. The object is thread-safe. DatabaseReader reader = new DatabaseReader.Builder(database).build(); InetAddress ipAddress = InetAddress.getByName(IP); // Replace "city" with the appropriate method for your database, e.g., // "country". CityResponse response = reader.city(ipAddress); Country country = response.getCountry(); System.out.println(country.getIsoCode()); // 'US' System.out.println(country.getName()); // 'United States' System.out.println(country.getNames().get("zh-CN")); // '美国' Subdivision subdivision = response.getMostSpecificSubdivision(); System.out.println(subdivision.getName()); // 'Minnesota' System.out.println(subdivision.getIsoCode()); // 'MN' City city = response.getCity(); System.out.println(city.getName()); // 'Minneapolis' Postal postal = response.getPostal(); System.out.println(postal.getCode()); // '55455' Location location = response.getLocation(); System.out.println(location.getLatitude()); // 44.9733 System.out.println(location.getLongitude()); // -93.2323 } } ================================================ FILE: src/main/java/com/java10/NewFeatures.java ================================================ /** * */ package com.java10; /** * @author MarkShen * @see https://www.oracle.com/technetwork/java/javase/10-relnote-issues-4108729.html * @see https://openjdk.org/projects/jdk/10/ */ public class NewFeatures { public static void main(String[] args) { // Java SE 10 Features and Enhancements } } ================================================ FILE: src/main/java/com/java11/NewFeatures.java ================================================ /** * */ package com.java11; /** * @author MarkShen * @see https://www.oracle.com/technetwork/java/javase/11-relnotes-5012447.html * @see https://openjdk.org/projects/jdk/11/ */ public class NewFeatures { public static void main(String[] args) { // Java SE 11 Features and Enhancements } } ================================================ FILE: src/main/java/com/java12/NewFeatures.java ================================================ /** * */ package com.java12; /** * @author MarkShen * @see https://www.oracle.com/technetwork/java/javase/12-relnote-issues-5211422.html * @see https://openjdk.org/projects/jdk/12/ */ public class NewFeatures { public static void main(String[] args) { // Java SE 12 Features and Enhancements } } ================================================ FILE: src/main/java/com/java13/NewFeatures.java ================================================ /** * */ package com.java13; /** * @author MarkShen * @see https://www.oracle.com/technetwork/java/13-relnote-issues-5460548.html * @see https://openjdk.org/projects/jdk/13/ */ public class NewFeatures { public static void main(String[] args) { // Java SE 13 Features and Enhancements } } ================================================ FILE: src/main/java/com/java14/Java14NewFeatures.java ================================================ package com.java14; /** * @author MarkShen1992 * @see https://www.oracle.com/technetwork/java/javase/14all-relnotes-5809668.html * @see https://www.codejava.net/java-se/java-14-new-features * @see https://openjdk.org/projects/jdk/14/ */ public class Java14NewFeatures { public static void main(String[] args) { } } ================================================ FILE: src/main/java/com/java15/NewFeatures.java ================================================ package com.java15; /** * jdk15 new feature * * https://openjdk.java.net/projects/jdk/15/ * https://javaalmanac.io/jdk/15/ * https://www.youtube.com/watch?v=uTNjeM0G9Nk * https://openjdk.org/projects/jdk/15/ */ public class NewFeatures { public static void main(String[] args) { System.out.println("jdk 15 new features."); } } ================================================ FILE: src/main/java/com/java16/Java16NewFeatures.java ================================================ package com.java16; /** * // Java 16 new features * // 1) https://openjdk.java.net/projects/jdk/16/ * // 2) https://mkyong.com/java/what-is-new-in-java-16/ * @author MarkShen */ public class Java16NewFeatures { public static void main(String[] args) { } } ================================================ FILE: src/main/java/com/java17/Java17NewFeatures.java ================================================ package com.java17; /** * https://www.baeldung.com/java-17-new-features https://mkyong.com/java/what-is-new-in-java-17/ * https://www.geeksforgeeks.org/jdk-17-new-features-in-java-17/ * @see https://openjdk.org/projects/jdk/17/ * * @author MarkShen */ public class Java17NewFeatures { public static void main(String[] args) { System.out.println("Java 17 new Features."); } } ================================================ FILE: src/main/java/com/java18/Java18Features.java ================================================ package com.java18; /** * Java 18 features * https://openjdk.org/projects/jdk/18/ * https://www.developer.com/java/java-18-features/ */ public class Java18Features { public static void main(String[] args) { } } ================================================ FILE: src/main/java/com/java19/Java19Features.java ================================================ package com.java19; /** * Java 19 features * https://openjdk.org/projects/jdk/19/ * https://www.infoworld.com/article/3653331/jdk-19-the-new-features-in-java-19.html */ public class Java19Features { public static void main(String[] args) { } } ================================================ FILE: src/main/java/com/java5/NewFeatures.java ================================================ /** * */ package com.java5; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @author MarkShen * */ public class NewFeatures { public static void print(int ...is) { for (int num : is) { System.out.println(num); } } public static void main(String[] args) { // Enhanced For loop List numbers = new ArrayList(); numbers.add(1); numbers.add(2); numbers.add(3); Iterator numbersIterator = null; for (numbersIterator = numbers.iterator(); numbersIterator.hasNext();) { System.out.println(numbersIterator.next());; } for (Object o : numbers) { System.out.println(o); } // VariableArguments print(new int[] {1,2,4}); // Static Imports // Enumerations(Typesafe Enums) // 自动装箱与自动拆箱(Autoboxing/Unboxing) // 引入泛型(Generics) // 元数据(注解) (Metadata Annotations) // 引入Instrumentation } } ================================================ FILE: src/main/java/com/java6/NewFeatures.java ================================================ /** * */ package com.java6; /** * @author MarkShen * @see https://www.oracle.com/technetwork/java/javase/features-141434.html * @see https://www.oracle.com/technical-resources/articles/javase/beta2.html */ public class NewFeatures { public static void main(String[] args) { // Java SE 6 Features and Enhancements } } ================================================ FILE: src/main/java/com/java7/NewFeatures.java ================================================ /** * */ package com.java7; /** * @author MarkShen * https://openjdk.org/projects/jdk7/features/ * @see https://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html */ public class NewFeatures { public static void main(String[] args) { // Java SE 7 Features and Enhancements } } ================================================ FILE: src/main/java/com/java8/Demo0100_LambdaRunnable.java ================================================ package com.java8; /** * @author MarkShen */ public class Demo0100_LambdaRunnable { public static void main(String[] args) { // 用lambda表达式实现Runnable // Java 8之前: new Thread(new Runnable() { @Override public void run() { System.out.println("Before Java8, too much code for too little to do"); } }).start(); //Java 8方式: new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start(); // 这个例子向我们展示了Java 8 lambda表达式的语法。你可以使用lambda写出如下代码 // (params) -> expression // (params) -> statement // (params) -> { statements } // 如果你的方法不对参数进行修改、重写,只是在控制台打印点东西的话 // () -> System.out.println("Hello Lambda Expressions"); // 如果你的方法接收两个参数 // (int even, int odd) -> even + odd } } ================================================ FILE: src/main/java/com/java8/Demo0200_LambdaIterator.java ================================================ package com.java8; import java.util.Arrays; import java.util.List; /** * @author MarkShen */ public class Demo0200_LambdaIterator { public static void main(String[] args) { // Java 8之前: List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); for (String feature : features) { System.out.println(feature); } System.out.println("---------------------------------"); // Java 8之后: features.forEach(n -> System.out.println(n)); // 使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示, // 看起来像C++的作用域解析运算符 System.out.println("---------------------------------"); features.forEach(System.out::println); } } ================================================ FILE: src/main/java/com/java8/Demo0300_LambdaPredicate.java ================================================ package com.java8; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; /** * @author MarkShen */ public class Demo0300_LambdaPredicate { public static void main(String[] args) { List languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp"); System.out.println("Languages which starts with J :"); // filter(languages, (str)->str.startsWith("J")); System.out.println("Languages which ends with a "); // filter(languages, (str)->str.endsWith("a")); System.out.println("Print all languages :"); filter(languages, (str)->true); System.out.println("Print no language : "); filter(languages, (str)->false); System.out.println("Print language whose length greater than 4:"); // filter(languages, (str)->str.length() > 4); // 甚至可以用and()、or()和xor()逻辑函数来合并Predicate, // 例如要找到所有以J开始,长度为四个字母的名字,你可以合并两个Predicate并传入 Predicate startsWithJ = (n) -> n.startsWith("J"); Predicate fourLetterLong = (n) -> n.length() == 4; languages.stream() .filter(startsWithJ.and(fourLetterLong)) .forEach((n) -> System.out.print("nName, which starts with 'J' and four letter long is : " + n)); } /** * filter * * @param names * @param condition */ public static void filter(List names, Predicate condition) { for (String name : names) { if (condition.test(name)) { System.out.println(name + " "); } } } // 更好的办法 public static void betterFilter(List names, Predicate condition) { names.stream().filter((name) -> (condition.test(name))).forEach((name) -> { System.out.println(name + " "); }); } } ================================================ FILE: src/main/java/com/java8/Demo0400_LambdaMapReduce.java ================================================ package com.java8; import java.util.Arrays; import java.util.IntSummaryStatistics; import java.util.List; import java.util.stream.Collectors; /** * @author MarkShen */ public class Demo0400_LambdaMapReduce { public static void main(String[] args) { // 不使用lambda表达式为每个订单加上12%的税 List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); for (Integer cost : costBeforeTax) { double price = cost + .12*cost; System.out.println(price); } // 使用lambda表达式 costBeforeTax.stream().map((cost) -> cost + .12*cost).forEach(System.out::println); // 为每个订单加上12%的税 // 老方法: double total = 0; for (Integer cost : costBeforeTax) { double price = cost + .12*cost; total = total + price; } System.out.println("Total : " + total); // 新方法: double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum + cost).get(); System.out.println("Total : " + bill); // 创建一个字符串列表,每个字符串长度大于2 List strList = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp"); List filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList()); System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered); // 将字符串换成大写并用逗号链接起来 List G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada"); String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", ")); System.out.println(G7Countries); // 用所有不同的数字创建一个正方形列表 List numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4); List distinct = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList()); System.out.printf("Original List : %s,  Square Without duplicates : %s %n", numbers, distinct); //获取数字的个数、最小值、最大值、总和以及平均值 List primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29); IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("Highest prime number in List : " + stats.getMax()); System.out.println("Lowest prime number in List : " + stats.getMin()); System.out.println("Sum of all prime numbers : " + stats.getSum()); System.out.println("Average of all prime numbers : " + stats.getAverage()); } } ================================================ FILE: src/main/java/com/java8/Demo0500_LambdaSimpleDemo.java ================================================ package com.java8; /** * @author MarkShen */ public class Demo0500_LambdaSimpleDemo { public static void main(String[] args) { // 1. 不需要参数,返回值为 5 // () -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值 // x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值 // (x, y) -> x – y // 4. 接收2个int型整数,返回他们的和 // (int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) // (String s) -> System.out.print(s) Demo0500_LambdaSimpleDemo tester = new Demo0500_LambdaSimpleDemo(); // 类型声明 MathOperation addition = (int a, int b) -> a + b; // 不用类型声明 MathOperation subtraction = (a, b) -> a - b; // 大括号中的返回语句 MathOperation multiplication = (int a, int b) -> { return a * b; }; // 没有大括号及返回语句 MathOperation division = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, addition)); System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction)); System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication)); System.out.println("10 / 5 = " + tester.operate(10, 5, division)); // 不用括号 GreetingService greetService1 = message -> System.out.println("Hello " + message); // 用括号 GreetingService greetService2 = (message) -> System.out.println("Hello " + message); greetService1.sayMessage("Runoob"); greetService2.sayMessage("Google"); } interface MathOperation { int operation(int a, int b); } interface GreetingService { void sayMessage(String message); } private int operate(int a, int b, MathOperation mathOperation) { return mathOperation.operation(a, b); } } ================================================ FILE: src/main/java/com/java8/Demo0600_Stream.java ================================================ package com.java8; import java.util.Arrays; import java.util.IntSummaryStatistics; import java.util.List; import java.util.Random; import java.util.stream.Collectors; /** * Stream 01 * @author MarkShen */ public class Demo0600_Stream { public static void main(String[] args) { /** +--------------------+ +------+ +------+ +---+ +-------+ | stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect| +--------------------+ +------+ +------+ +---+ +-------+ */ List strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List filtered = strings.stream().filter(e -> !e.isEmpty()).collect(Collectors.toList()); filtered.forEach(System.out::println); System.out.println(); Random random = new Random(); random.ints().limit(10).forEach(System.out::println); System.out.println(); List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); List squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList()); squaresList.forEach(System.out::println); List strs = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); long count = strs.stream().filter(s -> s.isEmpty()).count(); System.out.println(count); System.out.println(); Random rdm = new Random(); rdm.ints().limit(10).sorted().forEach(System.out::println); System.out.println(); List parallelStrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 long countNum = parallelStrings.parallelStream().filter(s -> s.isEmpty()).count(); System.out.println(countNum); System.out.println(); List ss = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List filteredList = ss.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList()); System.out.println("筛选列表: " + filteredList); String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", ")); System.out.println("合并字符串: " + mergedString); System.out.println(); List numberList = Arrays.asList(3, 2, 2, 3, 7, 3, 5); IntSummaryStatistics stats = numberList.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("列表中最大的数 : " + stats.getMax()); System.out.println("列表中最小的数 : " + stats.getMin()); System.out.println("所有数之和 : " + stats.getSum()); System.out.println("平均数 : " + stats.getAverage()); } } ================================================ FILE: src/main/java/com/java8/Demo0700_Stream.java ================================================ package com.java8; import java.util.*; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; /** * Stream 02 * @author MarkShen * https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html */ public class Demo0700_Stream { public static void main(String[] args) { /** * how to build stream */ // 1. Individual values Stream stream = Stream.of("a", "b", "c"); // 2. Arrays String [] strArray = new String[] {"a", "b", "c"}; stream = Stream.of(strArray); stream = Arrays.stream(strArray); // 3. Collections List list = Arrays.asList(strArray); stream = list.stream(); /** * number stream build */ IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println); IntStream.range(1, 3).forEach(System.out::println); IntStream.rangeClosed(1, 3).forEach(System.out::println); /** * other data structure from stream */ String[] strArr = {"a", "b", "c"}; // 1. Array, List, Set, Stack, String String[] sArr = Arrays.stream(strArr).toArray(String[]::new); List list1 = Arrays.stream(strArr).collect(Collectors.toList()); List list2 = Arrays.stream(strArr).collect(Collectors.toCollection(ArrayList::new)); Set set1 = Arrays.stream(strArr).collect(Collectors.toSet()); Stack stack1 = Arrays.stream(strArr).collect(Collectors.toCollection(Stack::new)); String str = Arrays.stream(strArr).collect(Collectors.joining(", ")); // convert all elements to upper case List myList = Arrays.asList("a1", "a2", "b1", "c2", "c1"); myList.stream() .filter(e -> e.startsWith("c")) .map(String::toUpperCase) .sorted() .forEach(System.out::println); Stream> inputStream = Stream.of( Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6) ); Stream outputStream = inputStream. flatMap((childList) -> childList.stream()); outputStream.forEach(System.out::println); System.out.println(); Stream.of("one", "two", "three", "four") .filter(e -> e.length() > 3) .peek(e -> System.out.println("Filtered value: " + e)) .map(String::toUpperCase) .peek(e -> System.out.println("Mapped value: " + e)) .collect(Collectors.toList()); System.out.println(); Stream.of("one", "two", "three", "four") .findFirst().ifPresent(System.out::println); System.out.println(); // 字符串连接,concat = "ABCD" String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat); // 求最小值,minValue = -3.0 double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min); // 求和,sumValue = 10, 有起始值 int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum); // 求和,sumValue = 10, 无起始值 sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get(); // 过滤,字符串连接,concat = "ace" concat = Stream.of("a", "B", "c", "D", "e", "F"). filter(x -> x.compareTo("Z") > 0). reduce("", String::concat); System.out.println(); Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9) .limit(3) .skip(2) .collect(Collectors.toList()).forEach(System.out::println); System.out.println(); List people = new ArrayList<>(); for (int i = 0; i < 10; i ++) { people.add(new Person(i, "name" + i)); } people.add(new Person(10, "name0")); // 根据 name 属性降序输出 people.stream() .sorted(Comparator.comparing(Person::getName).reversed()) .collect(Collectors.toList()) .forEach(System.out::println); Map> result = people.stream() .collect(Collectors.groupingBy(Person::getName)); System.out.println(result); long c = people.stream().filter(x -> x.getId() > 5).count(); System.out.println(c); long resultNum = people.stream().map(Person::getName).distinct().count(); System.out.println(resultNum); Optional min = people.stream().min(Comparator.comparing(Person::getId)); System.out.println(min.get()); Optional max = people.stream().max(Comparator.comparing(Person::getId)); max.ifPresent(System.out::println); Random seed = new Random(); Supplier random = seed::nextInt; Stream.generate(random).limit(10).forEach(System.out::println); // Another way IntStream.generate(() -> (int) (System.nanoTime() % 100)). limit(10).forEach(System.out::println); Stream.iterate(0, n -> n + 3).limit(10). forEach(x -> System.out.print(x + " ")); Map> resultMap = people.stream() .collect(Collectors.partitioningBy(p -> p.getId() < 6)); System.out.println(resultMap); } } ================================================ FILE: src/main/java/com/java8/Demo0800_Stream.java ================================================ package com.java8; import java.util.*; import java.util.stream.Collectors; public class Demo0800_Stream { public static void main(String[] args) { List persons = Arrays.asList(new Person(1, "Bob", 21, 1), new Person(2, "Alice", 25, 0), new Person(4, "Calvin", 26, 1), new Person(3, "Susan", 34, 0), new Person(5, "Trump", 70, 1)); Person persion = persons.stream().filter(p -> p.getName().equals("Bob")).findFirst().orElse(null); System.out.println(persion); // 人小于等于25的人的名字 List names = persons.stream().filter(p -> p.getAge() <= 25).map(Person::getName).collect(Collectors.toList()); System.out.println(names); // 分页查询实现 int pageIndex = 1; int pageSize = 2; int recordIndex = (pageIndex - 1) * pageSize; List pagedPerson = persons.stream().skip(recordIndex) // 每页第一条数据的位置 .limit(pageSize) // 页面大小 .collect(Collectors.toList()); System.out.println(pagedPerson); // Searching Optional any = persons.stream().filter(p -> p.getAge() < 25).findAny(); System.out.println(any); System.out.println(persons.stream().anyMatch(p -> p.getAge() < 25)); // Reordering Descending List sortedPersons = persons.stream().sorted(Comparator.comparing(Person::getAge).reversed()) // 升序 .collect(Collectors.toList()); System.out.println(sortedPersons); // Summarizing int sum = 0; sum = persons.stream().mapToInt(Person::getAge).reduce(0, (total, currentVal) -> total + currentVal); System.out.println(sum); sum = persons.stream().mapToInt(Person::getAge).sum(); System.out.println(sum); long count = 0; count = persons.stream().mapToInt(Person::getAge).count(); System.out.println(count); // calculating summary IntSummaryStatistics ageStatistics = persons.stream().mapToInt(Person::getAge).summaryStatistics(); System.out.println(ageStatistics.getAverage()); System.out.println(ageStatistics.getCount()); System.out.println(ageStatistics.getMax()); System.out.println(ageStatistics.getMin()); System.out.println(ageStatistics.getSum()); // Grouping Map> peopleGroupBySex = persons.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.toList())); System.out.println(peopleGroupBySex); Map> nameByGender = persons.stream() .collect(Collectors.groupingBy(Person::getSex, Collectors.mapping(Person::getName, Collectors.toList()))); System.out.println(nameByGender); Map averageAgeByGender = persons.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.averagingInt(Person::getAge))); System.out.println(averageAgeByGender); } } ================================================ FILE: src/main/java/com/java8/NewFeatures.java ================================================ /** * */ package com.java8; import java.util.Arrays; import java.util.List; /** * @author MarkShen * @see https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html * @see https://openjdk.org/projects/jdk8/features * @see http://www.importnew.com/16436.html */ public class NewFeatures { public static void main(String[] args) { // Java SE 8 Features and Enhancements List primes = Arrays.asList(new Integer[]{2, 3,5,7}); int factor = 2; primes.forEach(element -> { System.out.println(factor*element); }); primes.forEach(element -> System.out.println(factor*element)); primes.forEach(e -> System.out.println("Hello World " + e)); } } ================================================ FILE: src/main/java/com/java8/Person.java ================================================ package com.java8; public class Person { private int id; private String name; private int age; private int sex; public Person() {} public Person(int id, String name) { this.id = id; this.name = name; } public Person(int id, String name, int age, int sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age='" + age + '\'' + ", sex=" + sex + '}'; } } ================================================ FILE: src/main/java/com/java9/NewFeatures.java ================================================ /** * */ package com.java9; /** * @author MarkShen * @see https://docs.oracle.com/javase/9/whatsnew/toc.htm#JSNEW-GUID-C23AFD78-C777-460B-8ACE-58BE5EA681F6 * @see https://openjdk.org/projects/jdk9/ */ public class NewFeatures { public static void main(String[] args) { // Java SE 9 Features and Enhancements } } ================================================ FILE: src/main/java/com/jvm/OutOfMemoryException.java ================================================ package com.jvm; import java.util.ArrayList; import java.util.List; /** * @author MarkShen * @since 20190622 * Exception: OutOfMemoryError 抛出,可以改造成多线程往List里面加 */ public class OutOfMemoryException { static List os = new ArrayList<>(); public static void main(String[] args) { while (true) { os.add(new Object()); } } } ================================================ FILE: src/main/java/com/mark/concurrent01/T.java ================================================ package com.mark.concurrent01; /** * synchronized关键字 * 对对象加锁 * @author MarkShen */ public class T { private int count = 10; private static Object o = new Object(); // 有 static 和没有 static 有什么区别吗? public void m() { synchronized(o) { // 任何线程要执行下面的代码, 必须先拿到o的锁(互斥锁) count --; System.out.println(Thread.currentThread().getName() + "" + count); } } } ================================================ FILE: src/main/java/com/mark/concurrent02/T.java ================================================ package com.mark.concurrent02; /** * synchronized关键字 * 对当前对象加锁 * @author MarkShen */ public class T { private int count = 10; public void m() { // lock current object. synchronized(this) { // 任何线程要执行下面的代码, 必须先拿到this的锁, 锁定this对象, 锁对象, 而不是代码块 count --; System.out.println(Thread.currentThread().getName() + "" + count); } } } ================================================ FILE: src/main/java/com/mark/concurrent02/T2.java ================================================ package com.mark.concurrent02; /** * synchronized 对类加锁 * @author MarkShen */ public class T2 implements Runnable { private static int count = 10; @Override public void run() { // lock current object. synchronized(T2.class) { count --; System.out.println(Thread.currentThread().getName() + "" + count); } } public static void main(String[] args) { for (int i=0; i<10; i++) { new Thread(new T2(), "thread" + i + "-").start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent03/T.java ================================================ package com.mark.concurrent03; /** * synchronized 对对象加锁 * 加锁位置:堆内存对象 * @author MarkShen */ public class T { private int count = 10; public synchronized void m() { // 等同于 synchronized(this), 锁定当前对象 count --; System.out.println(Thread.currentThread().getName() + "" + count); } } ================================================ FILE: src/main/java/com/mark/concurrent04/T.java ================================================ package com.mark.concurrent04; /** * synchronized * 对对象加锁 * @author MarkShen */ public class T { private static int count = 10; public synchronized static void m() { // 等同于synchronized(com.mark.concurrent04.T.class) count --; System.out.println(Thread.currentThread().getName() + "" + count); } public static void mm() { synchronized (T.class) { // 考虑下,这里写synchronized(this)是否可以? 不可以, 因为静态方法,变量是不需要new出对象就可以访问的 count --; } } } ================================================ FILE: src/main/java/com/mark/concurrent05/T.java ================================================ package com.mark.concurrent05; /** * 分析下输出结果 * @author MarkShen */ public class T implements Runnable { private static int count = 10; @Override public /* synchronized */ void run() { // 等同于synchronized(com.mark.concurrent05.T.class), 原子操作 count --; System.out.println(Thread.currentThread().getName() + " count= " + count); } public static void main(String[] args) { T t = new T(); for (int i = 0; i < 5; i++) { new Thread(t, "Thread" + i).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent06/T.java ================================================ package com.mark.concurrent06; /** * synchronized 对对象加锁 * @author MarkShen */ public class T implements Runnable { private static int count = 10; @Override public synchronized void run() { // 等同于synchronized(com.mark.concurrent06.T.class), 原子操作 count --; System.out.println(Thread.currentThread().getName() + " count= " + count); } public static void main(String[] args) { T t = new T(); for (int i = 0; i < 5; i++) { new Thread(t, "Thread" + i).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent06/T2.java ================================================ package com.mark.concurrent06; import java.util.concurrent.atomic.AtomicInteger; /** * synchronized AtomicInteger * @author MarkShen */ public class T2 implements Runnable { private static AtomicInteger count = new AtomicInteger(10); // 原子操作,不会出现同样结果 @Override public void run() { // 等同于synchronized(com.mark.concurrent06.T.class), 原子操作 int andDecrement = count.getAndDecrement(); System.out.println(Thread.currentThread().getName() + " count= " + andDecrement); } public static void main(String[] args) { T2 t = new T2(); for (int i = 0; i < 5; i++) { new Thread(t, "Thread" + i).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent07/T.java ================================================ package com.mark.concurrent07; /** * synchronized 对方法加锁, 同步方法和非同步方法是否可以同时调用 * 在执行m1的过程之中,能否执行m2? * 同步方法执行时, 非同步方法可以执行 * @author MarkShen */ public class T { public synchronized void m1() { System.out.println(Thread.currentThread().getName() + "m1 start..."); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "m1 end..."); } public void m2() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "m2 ..."); } public static void main(String[] args) { T t = new T(); new Thread(() -> t.m1(), "t1").start(); new Thread(() -> t.m2(), "t2").start(); // new Thread(t::m1, "t1").start(); // new Thread(t::m2, "t2").start(); /** new Thread(new Runnable() { @Override public void run() { t.m1(); } }).start(); new Thread(new Runnable() { @Override public void run() { t.m2(); } }).start(); */ } } ================================================ FILE: src/main/java/com/mark/concurrent08/Account.java ================================================ package com.mark.concurrent08; import java.util.concurrent.TimeUnit; /** * 对业务写方法加锁 * 对业务读方法不加锁 * 容易产生脏读问题(dirty read) CopyOnWrite, 允不允许脏读? 根据实际业务场景斟酌使用。 * https://www.cnblogs.com/phoebus0501/archive/2011/02/28/1966709.html * @author MarkShen */ public class Account { String name; double balance; public synchronized void set(String name, double balance) { this.name = name; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } this.balance = balance; } public /* synchronized */ double getBalance(String name) { return this.balance; } public static void main(String[] args) { Account a = new Account(); new Thread(() -> a.set("张三", 100.0)).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(a.getBalance("zhangsan")); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(a.getBalance("zhangsan")); } } ================================================ FILE: src/main/java/com/mark/concurrent09/T.java ================================================ package com.mark.concurrent09; import java.util.concurrent.TimeUnit; /** * 一个同步方法可以调用另一个同步方法。 一个线程已经获得某个对象的锁,再次申请的时候仍然会得到该对象的锁 * 也就是说synchronized获得的锁是可重入的 * synchronized 锁升级: https://blog.csdn.net/tongdanping/article/details/79647337 * @author MarkShen */ public class T implements Runnable { @Override public synchronized void run() { System.out.println("m1 start..."); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } m2(); } synchronized void m2() { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("m2"); } public static void main(String[] args) { T t = new T(); new Thread(t::run).start(); } } ================================================ FILE: src/main/java/com/mark/concurrent10/T.java ================================================ package com.mark.concurrent10; import java.util.concurrent.TimeUnit; /** * 这里是继承中可能发生的情形,子类调用父类的同步方法, 锁定同一对象 * @author MarkShen */ public class T { synchronized void m1() { System.out.println("m1 start..."); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("m1 end..."); } public static void main(String[] args) { new TT().m1(); } } class TT extends T { @Override synchronized void m1() { System.out.println("child m1 start..."); super.m1(); System.out.println("child m1 end..."); } } ================================================ FILE: src/main/java/com/mark/concurrent11/T.java ================================================ package com.mark.concurrent11; import java.util.concurrent.TimeUnit; /** * 程序在执行过程中, 如果出现异常, 默认情况锁会被释放 * 所以,在并发处理的过程中,有异常要多加小心, 不然可能会发生不一致的情况 * 比如, 在一个App web处理过程中, 多个servlet线程共同访问同一资源,这时如果异常处理不合适, * 在第一个线程中抛出异常, 其他线程就会进入同步代码区, 有可能会访问到异常产生时的数据。 * 因此, 要非常小心处理同步业务中的异常 * @author MarkShen */ public class T { int count = 0; synchronized void m() { System.out.println(Thread.currentThread().getName() + " start"); while(true) { count ++; System.out.println(Thread.currentThread().getName() + " count= " + count); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 5) { int i = 1 / 0; // 此处抛出异常, 锁将被释放, 要不想被释放, 加catch,让循环继续 } } } public static void main(String[] args) { T t = new T(); Runnable r = new Runnable() { @Override public void run() { t.m(); } }; new Thread(r, "t1").start(); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(r, "t2").start(); } } ================================================ FILE: src/main/java/com/mark/concurrent12/T.java ================================================ package com.mark.concurrent12; import java.util.concurrent.TimeUnit; /** * volatile关键字, 是一个变量在多线程间可见 * A, B线程都用到一个变量, Java默认是A线程中保留一份copy, 这样如果B线程修改了该变量, 则线程A未必知道。 * 使用volatile关键字可以使所有线程都会读到变量的修改值 * * 在下面的代码中, running时存在于对内存的t对象中 * 当线程t1开通的时候, 会把running值从内存中读到t1线程的工作区,在运行中直接使用这个copy,并不会每次都去 * 读取内存,这样, 当主线程修改running的值后,t1线程感知不到, 所以不会停止运行。 * * 使用volatile, 将会强制所有线程都去对内存中读取running的值, 缓存过期通知 * * 深入理解请阅读:http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html * * volatile并不能保证多个线程共同修改running变量时所带来的不一致问题, 也就是说volatile不能代替synchronized * * Java线程处理的内存模型, 深入了解《深入Java虚拟机》 JMM * JDK 并发容器, 能用volatile的地方,就不要用锁 * @author MarkShen * */ public class T { /** * https://www.cnblogs.com/Mushrooms/p/5151593.html * * 补充内容:分享点儿知识,内容就是CPU内部的寄存器。就这个程序来说,有两个线程。一个是主线程, * 一个是自己启动的线程。当自己启动的线程运行时,running这个变量的值会被CPU把值从内存中读到 * CPU中的寄存器(即CPU中的cache)中。为什么这么做呢?因为CPU的速度要比内存的速度快,内存的速 * 度比硬盘快。所以要把running中的数据copy一份到内存中处理。但是,没有加volatile关键字的变 * 量running,当主线程已经把running改为false,自己启动的线程依然不能停下来。因为它读的是CPU * 中running。主线程改的内存中的running。两个线程读写的变量的存储位置不同。 * * 而volatile关键字就是为了解决这个问题而出现的。其作用是,当主线程对内存中的变量running修改 * 后,就会通知CPU中的变量running,你那个值已经不是最新的了。这时候,自己启动的线程会重新读一 * 遍内存中的running变量。 */ // volatile 解决了线程间的可见性(观察者模式) volatile boolean running = true; // 对比一下有无volatile情况下, 整个程序运行的结果 void m() { System.out.println("m start"); while(running) { // try { // TimeUnit.SECONDS.sleep(1); // } catch (InterruptedException e) { // e.printStackTrace(); // } } System.out.println("m end"); } public static void main(String[] args) { T t = new T(); new Thread(t::m, "t1").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } t.running = false; } } ================================================ FILE: src/main/java/com/mark/concurrent13/T.java ================================================ package com.mark.concurrent13; import java.util.ArrayList; import java.util.List; /** * volatile 并不能保证多个线程共同修改running变量时所带来的不一致问题,也就是说volatile不能 * 代替synchronized运行下面的程序, 并分析结果。 * * volatile与synchronized关键字区别? * volatile 只能保证可见性,效率高 * synchronized 既保证可见性,又保证原子性,效率低 * @author MarkShen */ public class T { volatile int count = 0; void m() { for (int i = 0; i < 10000; i++) { count ++; } } public static void main(String[] args) { T t = new T(); List threads = new ArrayList<>(); for (int i = 0; i < 10; i ++) { threads.add(new Thread(t::m, "thread-" + i)); } threads.forEach((o) -> o.start()); threads.forEach((o) -> { try { o.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(t.count); } } ================================================ FILE: src/main/java/com/mark/concurrent14/T.java ================================================ package com.mark.concurrent14; import java.util.ArrayList; import java.util.List; /** * 对比上一个程序,可以用synchronized解决, synchronized既保证原子性,又保证可见性; * 而volatile只保证可见性 * @author MarkShen */ public class T { /*volatile*/ int count = 0; synchronized void m() { for (int i = 0; i < 10000; i++) { count ++; } } public static void main(String[] args) { T t = new T(); List threads = new ArrayList(); for (int i = 0; i < 10; i ++) { threads.add(new Thread(t::m, "thread-" + i)); } threads.forEach((o) -> o.start()); threads.forEach((o) -> { try { o.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(t.count); } } ================================================ FILE: src/main/java/com/mark/concurrent15/T.java ================================================ package com.mark.concurrent15; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * 解决同样的问题更高效的方法,使用AtomicXXX类 * AtomXXX类本身方法都是原子性的, 但不能保证多方法连续调用的原子性。 * @author MarkShen */ public class T { /*volatile int count = 0;*/ AtomicInteger count = new AtomicInteger(0); /*synchronized*/ void m() { for (int i = 0; i < 10000; i++) { // if (count.get() < 1000) // 这个位置没有原子性 count.incrementAndGet(); // 替换 count ++; } } public static void main(String[] args) { T t = new T(); List threads = new ArrayList(); for (int i = 0; i < 10; i ++) { threads.add(new Thread(t::m, "thread-" + i)); } threads.forEach((o) -> o.start()); threads.forEach((o) -> { try { o.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(t.count); } } ================================================ FILE: src/main/java/com/mark/concurrent16/T.java ================================================ package com.mark.concurrent16; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * synchronized的优化 * 同步代码中的语句越少越好 * 比较m1和m2 * @author MarkShen */ public class T { int count = 0; synchronized void m1() { // do something need not sync try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } // 业务逻辑中只有下面这句需要sync,这时不应该给整个方法上锁 count ++; try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } void m2() { // do something need not sync try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } // 业务逻辑中只有下面这句需要sync,这时不应该给整个方法上锁 // 采用细粒度的锁, 可以使用线程争用时间变短,从而提高效率 synchronized(this) { count ++; } // do something need not sync try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { T t = new T(); List threads = new ArrayList(); for (int i = 0; i < 10; i ++) { threads.add(new Thread(t::m1, "thread-" + i)); } threads.forEach((o) -> o.start()); threads.forEach((o) -> { try { o.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(t.count); } } ================================================ FILE: src/main/java/com/mark/concurrent17/T.java ================================================ package com.mark.concurrent17; import java.util.concurrent.TimeUnit; /** * 锁定某对象o, 如果o的属性发生改变,不影响锁的使用 * 但如果o变成另外一个对象,则锁定的对象发生改变 * 应该避免将锁定对象的引用变成另外的对象 * 锁在堆内存new出来的对象 * @author MarkShen */ public class T { Object o = new Object(); void m() { synchronized(o) { while (true) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } } } public static void main(String[] args) { T t = new T(); // start first thread new Thread(t::m, "t1").start(); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } // create second thread Thread t2 = new Thread(t::m, "t2"); // 锁对象发生改变,所以t2线程得以执行 t.o = new Object(); // 如果注释掉这句话,线程2将永远得不到执行 t2.start(); } } ================================================ FILE: src/main/java/com/mark/concurrent18/T.java ================================================ package com.mark.concurrent18; /** * 不要以字符串常量作为锁定对象 * 在下面的例子中,m1和m2其实锁定的是同一对象 * 这种情况还会发生比较诡异的现象,比如你用到一个类库,在该类库中代码锁定了字符串 "Hello" * 但是你都不到源码,所以你在自己源码中也锁定了 "Hello", 这时就会发生非常诡异的死锁阻塞, * 因为你的程序和使用到的类库不经意间使用了同一把锁 * * jetty open source software. * * @author MarkShen */ public class T { String s1 = "Hello"; String s2 = "Hello"; void m1() { synchronized (s1) { } } void m2() { synchronized (s2) { } } } ================================================ FILE: src/main/java/com/mark/concurrent19/MyContainer1.java ================================================ package com.mark.concurrent19; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * 曾经的面试题(淘宝?) * 实现一个程序,提供两个方法, add, size * 写两个线程,线程一添加10个元素到容器中,线程2实现监控线程的个数, * 当个数到5个时,线程2给出提示并结束 * * 分析下面的程序,能完成这个功能吗? * @author MarkShen */ public class MyContainer1 { List list = new ArrayList(); public void add(Object o) { list.add(o); } public int size() { return list.size(); } public static void main(String[] args) { MyContainer1 c = new MyContainer1(); new Thread(() -> { for(int i=0; i<10; i++) { c.add(new Object()); System.out.println("add" + i); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t1").start(); new Thread(() ->{ while(true) { if (c.size() == 5) { break; } } System.out.println("Thread2 finished..."); }, "t2").start(); } } ================================================ FILE: src/main/java/com/mark/concurrent19/MyContainer2.java ================================================ package com.mark.concurrent19; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * 曾经的面试题(淘宝?) * 实现一个程序,提供两个方法, add, size * 写两个线程,线程一添加10个元素到容器中,线程2实现监控线程的个数, * 当个数到5个时,线程2给出提示并结束 * * 添加volatile,使t2可以得到通知, 但是,t2线程的死循环很浪费CPU, 如果不用死循环该怎么做? * 面试题要比你的竞争者好, 比别人牛,面试不是及格就好,面试要拿到100分,110分,120分。总之,要与众不同 * 怎么展现自己(重要) * * 问题: * 不是很精确 * 浪费CPU资源 * @author MarkShen */ public class MyContainer2 { // 添加volatile,使t2可以得到通知 volatile List list = new ArrayList(); public void add(Object o) { list.add(o); } public int size() { return list.size(); } public static void main(String[] args) { MyContainer2 c = new MyContainer2(); new Thread(() -> { for(int i=0; i<10; i++) { c.add(new Object()); System.out.println("add" + i); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t1").start(); new Thread(() ->{ while(true) { if (c.size() == 5) { break; } } System.out.println("Thread2 finished..."); }, "t2").start(); } } ================================================ FILE: src/main/java/com/mark/concurrent19/MyContainer3.java ================================================ package com.mark.concurrent19; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * 曾经的面试题(淘宝?) * 实现一个程序,提供两个方法, add, size * 写两个线程,线程一添加10个元素到容器中,线程2实现监控线程的个数, * 当个数到5个时,线程2给出提示并结束 * * 添加volatile,使t2可以得到通知, 但是,t2线程的死循环很浪费CPU, 如果不用死循环该怎么做? * 面试题要比你的竞争者好, 比别人牛 * 怎么展现自己(重要) * * 这里使用wait和notify做到, wait会释放锁, 而notify不会释放锁(被锁定对象的wait和notify方法) * 需要注意的是,运用这种方法,必须保证t2先执行,先让t2监听才可以 * * 阅读线面程序给出结果 * 可以读到输出结果并不是size==5时, t2退出, 而是t1结束时通知t2才收到通知而退出 * 想想为什么??? * notify不会释放锁, sleep也不释放锁 * @author MarkShen */ public class MyContainer3 { // 添加volatile,使t2可以得到通知 volatile List list = new ArrayList(); public void add(Object o) { list.add(o); } public int size() { return list.size(); } public static void main(String[] args) { MyContainer3 c = new MyContainer3(); final Object lock = new Object(); new Thread(() -> { synchronized(lock) { System.out.println("t2 启动"); if (c.size() != 5) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("t2 结束"); } }, "t2").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { synchronized(lock) { for (int i=0; i<10; i++) { c.add(new Object()); System.out.println("add " + i); if (c.size() == 5) { lock.notify(); } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "t1").start(); } } ================================================ FILE: src/main/java/com/mark/concurrent19/MyContainer4.java ================================================ package com.mark.concurrent19; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * 曾经的面试题(淘宝?) * 实现一个程序,提供两个方法, add, size * 写两个线程,线程一添加10个元素到容器中,线程2实现监控线程的个数, * 当个数到5个时,线程2给出提示并结束 * * 添加volatile,使t2可以得到通知, 但是,t2线程的死循环很浪费CPU, 如果不用死循环该怎么做? * 面试题要比你的竞争者好, 比别人牛 * 怎么展现自己(重要) * * 这里使用wait和notify做到, wait会释放锁, 而notify不会释放锁(被锁定对象的wait和notify方法) * 需要注意的是,运用这种方法,必须保证t2先执行,先让t2监听才可以 * * 阅读线面程序给出结果 * 可以读到输出结果并不是size==5时, t2退出, 而是t1结束时通知t2才收到通知而退出 * 想想为什么??? * notify不会释放锁, sleep也不释放锁 * * notify之后,t1必须释放锁, t2退出后,也必须notify, 通知t1继续执行, 整个通信过程比较繁琐 * @author MarkShen */ public class MyContainer4 { // 添加volatile,使t2可以得到通知 volatile List list = new ArrayList(); public void add(Object o) { list.add(o); } public int size() { return list.size(); } public static void main(String[] args) { MyContainer4 c = new MyContainer4(); final Object lock = new Object(); new Thread(() -> { synchronized(lock) { System.out.println("t2 启动"); if (c.size() != 5) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 通知t1继续执行 lock.notify(); System.out.println("t2 结束"); } }, "t2").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { synchronized(lock) { for (int i=0; i<10; i++) { c.add(new Object()); System.out.println("add " + i); if (c.size() == 5) { lock.notify(); // 释放锁,让t2得以执行 try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "t1").start(); } } ================================================ FILE: src/main/java/com/mark/concurrent19/MyContainer5.java ================================================ package com.mark.concurrent19; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * 曾经的面试题(淘宝?) * 实现一个程序,提供两个方法, add, size * 写两个线程,线程一添加10个元素到容器中,线程2实现监控线程的个数, * 当个数到5个时,线程2给出提示并结束 * * 添加volatile,使t2可以得到通知, 但是,t2线程的死循环很浪费CPU, 如果不用死循环该怎么做? * 面试题要比你的竞争者好, 比别人牛 * 怎么展现自己(重要) * * 这里使用wait和notify做到, wait会释放锁, 而notify不会释放锁(被锁定对象的wait和notify方法) * 需要注意的是,运用这种方法,必须保证t2先执行,先让t2监听才可以 * * 阅读线面程序给出结果 * 可以读到输出结果并不是size==5时, t2退出, 而是t1结束时通知t2才收到通知而退出 * 想想为什么??? * notify不会释放锁, sleep也不释放锁 * * notify之后,t1必须释放锁, t2退出后,也必须notify, 通知t1继续执行, 整个通信过程比较繁琐 * * 使用Latch(门闩)代替wait, notify来进行通知 * 好处通信方式简单, 同时可以指定等待时间 * 使用await和countdown方法来代替wait, notify * CountDownLatch不涉及锁定,当count的值为0时当前线程继续运行 * 当不涉及同步,只有涉及线程通信的时候,用synchronized + wait/notify就太重了 * 这时应该考虑使用CountDownLatch/cyclicbarrier/semaphore * * @author MarkShen */ public class MyContainer5 { // 添加volatile,使t2可以得到通知 volatile List list = new ArrayList(); public void add(Object o) { list.add(o); } public int size() { return list.size(); } public static void main(String[] args) { MyContainer5 c = new MyContainer5(); CountDownLatch latch = new CountDownLatch(1); new Thread(() -> { System.out.println("t2 启动"); if (c.size() != 5) { try { latch.await(); // 可以指定等待时间 // latch.await(5000, TimeUnit.MILLISECONDS) } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("t2 结束"); }, "t2").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { for (int i=0; i<10; i++) { c.add(new Object()); System.out.println("add " + i); if (c.size() == 5) { // 打开门闩,让t2得以执行 latch.countDown(); } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t1").start(); } } ================================================ FILE: src/main/java/com/mark/concurrent20/ReentrantLock1.java ================================================ package com.mark.concurrent20; import java.util.concurrent.TimeUnit; /** * reentrantlock用于代替synchronized * 本例中由于m1锁定this, 只有m1执行完毕的时候, m2才能执行 * 这里是复制synchronized最原始的语义 * * @author MarkShen */ public class ReentrantLock1 { synchronized void m1() { for (int i = 0; i < 10; i++) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + i); } } synchronized void m2() { System.out.println("m2......"); } public static void main(String[] args) { ReentrantLock1 r1 = new ReentrantLock1(); new Thread(r1::m1).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(r1::m2).start(); } } ================================================ FILE: src/main/java/com/mark/concurrent20/ReentrantLock2.java ================================================ package com.mark.concurrent20; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 使用reentrantlock可以完成相同的功能 * 需要注意的是,必须要必须要必须要手动释放锁 * 使用synchronized锁定的话如果遇到异常,JVM会自动释放锁,但是lock必须手动释放锁, * 因此经常在finally中进行锁的释放 * @author MarkShen */ public class ReentrantLock2 { Lock lock = new ReentrantLock(); void m1() { lock.lock(); // synchronized(this) try { for (int i = 0; i < 10; i++) { TimeUnit.SECONDS.sleep(1); System.out.println(i); } } catch (InterruptedException e1) { e1.printStackTrace(); } finally { lock.unlock(); } } void m2() { lock.lock(); System.out.println("m2......"); lock.unlock(); } public static void main(String[] args) { ReentrantLock2 r1 = new ReentrantLock2(); new Thread(r1::m1).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(r1::m2).start(); } } ================================================ FILE: src/main/java/com/mark/concurrent20/ReentrantLock3.java ================================================ package com.mark.concurrent20; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 使用reentrantlock可以进行尝试锁定"tryLock", 这样无法锁定,或者在指定时间内无法锁定, * 线程可以决定是否继续等待 * * @author MarkShen */ public class ReentrantLock3 { Lock lock = new ReentrantLock(); void m1() { lock.lock(); // synchronized(this) try { for (int i = 0; i < 10; i++) { TimeUnit.SECONDS.sleep(1); System.out.println(i); } } catch (InterruptedException e1) { e1.printStackTrace(); } finally { lock.unlock(); } } /** * 使用tryLock进行尝试锁定,不过锁定与否,方法都将继续执行 * 可根据tryLock的返回值来确定是否锁定 * 也可以指定tryLock的时间,有tryLock(time)抛出异常, * 所以要注意unlock的处理必须放到finally中 */ synchronized void m2() { // 如果锁定了怎么办, 没锁定怎么办, 逻辑根据返回值来判断 /*boolean locked = lock.tryLock(); System.out.println("m2......" + locked); if (locked) lock.unlock();*/ boolean locked = lock.tryLock(); try { locked = lock.tryLock(5, TimeUnit.SECONDS); System.out.println("m2......" + locked); } catch (InterruptedException e) { e.printStackTrace(); } finally { if (locked) lock.unlock(); } } public static void main(String[] args) { ReentrantLock3 r1 = new ReentrantLock3(); new Thread(r1::m1).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(r1::m2).start(); } } ================================================ FILE: src/main/java/com/mark/concurrent20/ReentrantLock4.java ================================================ package com.mark.concurrent20; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 使用reentrantlock可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应, * 在一个线程中等待锁的过程中, 可能被打断 * * @author MarkShen * */ public class ReentrantLock4 { public static void main(String[] args) { Lock lock = new ReentrantLock(); Thread t1 = new Thread(() -> { lock.lock(); // synchronized(this) try { System.out.println("t1 start"); TimeUnit.SECONDS.sleep(Integer.MAX_VALUE); System.out.println("t1 end"); } catch (InterruptedException e1) { e1.printStackTrace(); } finally { lock.unlock(); } }); t1.start(); Thread t2 = new Thread(() -> { boolean locked = false; // 防止异常抛出 try { // lock.lock(); // synchronized(this) lock.lockInterruptibly(); // 可对interrupt()方法做出响应 // 防止异常抛出 locked = lock.tryLock(); System.out.println("t2 start"); TimeUnit.SECONDS.sleep(Integer.MAX_VALUE); System.out.println("t2 end"); } catch (InterruptedException e1) { System.out.println("interrupted..."); } finally { if (locked) lock.unlock(); } }); t2.start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } t2.interrupt(); // Interrupts this thread. } } ================================================ FILE: src/main/java/com/mark/concurrent20/ReentrantLock5.java ================================================ package com.mark.concurrent20; import java.util.concurrent.locks.ReentrantLock; /** * reentrantlock还可以指定为公平锁,默认的synchronized为非公平锁 * 谁等的时间长,谁获得锁 * Java 线程调度器 * @author MarkShen */ public class ReentrantLock5 extends Thread { private ReentrantLock lock = new ReentrantLock(true); // 参数为true为公平锁,请对比输入结果 @Override public void run() { for (int i = 0; i < 100; i++) { lock.lock(); try { System.out.println(Thread.currentThread().getName() + "获得锁"); } finally { lock.unlock(); } } } public static void main(String[] args) { ReentrantLock5 r1 = new ReentrantLock5(); Thread t1 = new Thread(r1); Thread t2 = new Thread(r1); t1.start(); t2.start(); } } ================================================ FILE: src/main/java/com/mark/concurrent21/MyContainer1.java ================================================ package com.mark.concurrent21; import java.util.LinkedList; import java.util.concurrent.TimeUnit; /** * 面试题 * 写一个固定容量同步容器, 拥有put,get方法,以及getCount方法 * 能够支持2个生产线程, 10个消费线程的阻塞调用 * * 使用wait和notify/notifyAll来实现 * Effective Java: wait 往往与 while一起使用 * * @author MarkShen * */ public class MyContainer1 { final private LinkedList lists = new LinkedList<>(); final private int MAX = 10; // 最多是个元素 private int count = 0; public synchronized void put(T t) { while (lists.size() == MAX) { // 为什么要用while, 不用if? /** * 两个以上线程的时候 */ try { this.wait(); // 释放锁 } catch (InterruptedException e) { e.printStackTrace(); } } lists.add(t); ++ count; this.notifyAll(); // 通知消费者线程进行消费 } public synchronized T get() { T t = null; while (lists.size() == 0) { // 为什么要用while, 不用if? try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } t = lists.removeFirst(); -- count; this.notifyAll(); // 通知生产者线程进行生产 return t; } public static void main(String[] args) { MyContainer1 c = new MyContainer1(); // start consumer thread for (int i = 0; i < 10; i ++) { new Thread(() -> { for (int j = 0; j < 5; j++) { System.out.println(c.get()); } }, "c" + i).start(); } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } // start producer thread for (int i = 0; i < 2; i ++) { new Thread(() -> { for (int j = 0; j < 25; j++) { c.put(Thread.currentThread().getName() + " " + j); } }, "p" + i).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent21/MyContainer2.java ================================================ package com.mark.concurrent21; import java.util.LinkedList; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 面试题 * 写一个固定容量同步容器, 拥有put,get方法,以及getCount方法 * 能够支持2个生产线程, 10个消费线程的阻塞调用 * * Effective Java: wait 往往与 while一起使用 * * 使用Lock和Condition来实现 * 对比两种方式,Condition的方式可以更加精确的指定哪些线程被唤醒 * * @author MarkShen */ public class MyContainer2 { final private LinkedList lists = new LinkedList<>(); final private int MAX = 10; // 最多是个元素 private int count = 0; private Lock lock = new ReentrantLock(); // 精确指定 private Condition producer = lock.newCondition(); private Condition consumer = lock.newCondition(); public void put(T t) { try { lock.lock(); while (lists.size() == MAX) { // 为什么要用while, 不用if? producer.await(); } lists.add(t); ++ count; consumer.signalAll(); // 通知消费者线程进行消费 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public T get() { T t = null; try { lock.lock(); while (lists.size() == 0) { // 为什么要用while, 不用if? consumer.await(); } t = lists.removeFirst(); ++ count; producer.signalAll(); // 通知消费者线程进行消费 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } return t; } public static void main(String[] args) { MyContainer2 c = new MyContainer2(); // start consumer thread for (int i = 0; i < 10; i ++) { new Thread(() -> { for (int j = 0; j < 5; j++) { System.out.println(c.get()); } }, "c" + i).start(); } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } // start producer thread for (int i = 0; i < 2; i ++) { new Thread(() -> { for (int j = 0; j < 25; j++) { c.put(Thread.currentThread().getName() + " " + j); } }, "p" + i).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent22/ThreadLocal1.java ================================================ package com.mark.concurrent22; import java.util.concurrent.TimeUnit; /** * * @author MarkShen */ public class ThreadLocal1 { volatile static Person p = new Person(); public static void main(String[] args) { new Thread(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(p.name); }).start(); new Thread(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } p.name = "lisi"; }).start(); } } class Person { String name = "zhangsan"; } ================================================ FILE: src/main/java/com/mark/concurrent22/ThreadLocal2.java ================================================ package com.mark.concurrent22; import java.util.concurrent.TimeUnit; /** * ThreadLocal线程局部变量 * 空间换时间,synchronized时间换空间 * 比如Hibernate中session就是存放在ThreadLocal中的, 避免synchronized的使用。 * * 运行下面程序,理解ThreadLocal * 在使用的时候,状态改变,自己维护这个状态,不用通知其他线程,这时使用ThreadLocal * 可能会导致内存泄漏 * * 使用场景:自己进行改变,自己维护这个状态,不用其他线程 * https://blog.csdn.net/zsfsoftware/article/details/50933151 * @author MarkShen * */ public class ThreadLocal2 { // 每个线程各放一份,修改只改自己的一份, 不会是别人的一份,以空间换时间,效率更高 static ThreadLocal tl = new ThreadLocal<>(); public static void main(String[] args) { new Thread(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(tl.get()); }).start(); new Thread(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } tl.set(new Person()); }).start(); } static class Person { String name = "zhangsan"; } } ================================================ FILE: src/main/java/com/mark/concurrent23/Singleton.java ================================================ package com.mark.concurrent23; import java.util.Arrays; /** * 线程安全的单利模式 * 最理想的单利模式实现方法 * @author MarkShen */ public class Singleton { private Singleton() {} private static class Inner { private static Singleton instance = new Singleton(); } public static Singleton getInstance() { return Inner.instance; } public static void main(String[] args) { Thread[] threads = new Thread[200]; for (int i=0; i { System.out.println(Singleton.getInstance()); }); } Arrays.asList(threads).forEach(o -> o.start()); } } ================================================ FILE: src/main/java/com/mark/concurrent24/TicketSeller1.java ================================================ package com.mark.concurrent24; import java.util.ArrayList; import java.util.List; /** * 有n张火车票,每张票都有一编号 * 同时有10个窗口在对外售票 * 写一个模拟程序 * * 分析下面程序可能产生那些问题? * 重复销售, 超量销售 * @author MarkShen * */ public class TicketSeller1 { static List tickets = new ArrayList(); static { for (int i=0; i<10000; i++) tickets.add("票编号:" + i); } public static void main(String[] args) { for (int i=0; i<10; i++) { new Thread(() -> { while(tickets.size() > 0) { System.out.println("销售了--" + tickets.remove(0)); // remove方法非原子性 } }).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent24/TicketSeller2.java ================================================ package com.mark.concurrent24; import java.util.Vector; import java.util.concurrent.TimeUnit; /** * 有n张火车票,每张票都有一编号 * 同时有10个窗口在对外售票 * 写一个模拟程序 * * 分析下面程序可能产生那些问题? * 重复销售, 超量销售 * @author MarkShen * */ public class TicketSeller2 { static Vector tickets = new Vector(); // 本身就是同步容器 static { for (int i=0; i<10000; i++) tickets.add("票编号:" + i); } public static void main(String[] args) { for (int i=0; i<10; i++) { new Thread(() -> { while(tickets.size() > 0) { // 原子性 // 中间部分不是原子性的 /*try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); }*/ System.out.println("销售了--" + tickets.remove(0)); // 原子性 } }).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent24/TicketSeller3.java ================================================ package com.mark.concurrent24; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * 有n张火车票,每张票都有一编号 * 同时有10个窗口在对外售票 * 写一个模拟程序 * * 分析下面程序可能产生那些问题? * 没有问题了,但效率不高 * @author MarkShen */ public class TicketSeller3 { static List tickets = new ArrayList(); static { for (int i=0; i<10000; i++) tickets.add("票编号:" + i); } public static void main(String[] args) { for (int i=0; i<10; i++) { new Thread(() -> { while (true) { synchronized(tickets) { if (tickets.size() < 0) { break; } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("销售了--" + tickets.remove(0)); } } }).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent24/TicketSeller4.java ================================================ package com.mark.concurrent24; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; /** * 有n张火车票,每张票都有一编号 * 同时有10个窗口在对外售票 * 写一个模拟程序 * * 分析下面程序可能产生那些问题? * 没问题,效率高 * @author MarkShen * */ public class TicketSeller4 { static Queue tickets = new ConcurrentLinkedQueue(); // Queue里面不应该有空值 static { for (int i = 0; i < 1000; i ++) tickets.add("票编号:" + i); } public static void main(String[] args) { for (int i = 0; i < 10; i ++) { new Thread(() -> { while(true) { String s = tickets.poll(); // 在写if ... else ... 代码的时候,一定要加大括号。下面的代码是反例 if (s == null) break; else System.out.println("销售了--" + s); } }).start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent25/T01_ConcurrentMap.java ================================================ package com.mark.concurrent25; import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.CountDownLatch; /** * 阅读ConcurrentSkipListMap * http://blog.csdn.net/sunxianghuang/article/details/52221913 * * 总结 * 1. 对于Map/Set的选择与使用 * 1) 不加锁(单线程时候) * HashMap * TreeMap * LinkedHashMap * * 2) 加锁(多线程场景) * 并发不高 * Hashtable * Collections.synchronizedXXX * * 并发高的时候 * ConcurrentHashMap * * 并发性高且排序 * ConcurrentSkipListMap * * 2. 队列 * ArrayList * LinkedList * Collections.synchronizedXXX * CopyOnWriteList * * 高并发场景 * ConcurrentLinkedQueue // 非阻塞 * BlockingQueue // 阻塞 * LinkedBlockingQueue * ArrayBlockingQueue * TransferQueue * SynchronousQueue * DelayQueue:定时任务 * * @author MarkShen */ public class T01_ConcurrentMap { public static void main(String[] args) { // 不同容器在多线程并发下的效率问题 // Map map = new ConcurrentHashMap<>(); // Map map = new ConcurrentSkipListMap<>(); // 高并发, 排序 // Map map = new Hashtable<>(); Map map = new HashMap(); // Collections.synchronizedXXX // TreeMap Random r = new Random(); Thread[] threads = new Thread[100]; CountDownLatch latch = new CountDownLatch(threads.length); long start = System.currentTimeMillis(); for (int i=0; i { for (int j=0; j<10000; j++) map.put("a" + r.nextInt(100000), "a" + r.nextInt(100000)); latch.countDown(); }); } Arrays.asList(threads).forEach(t->t.start()); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println(end - start); } } ================================================ FILE: src/main/java/com/mark/concurrent25/T02_CopyOnWriteList.java ================================================ package com.mark.concurrent25; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; /** * 写时复制容器 copy on write * 多线程下,写效率低, 读效率高 * * 应用场景:适合写少读多的情况 * * @author MarkShen */ public class T02_CopyOnWriteList { public static void main(String[] args) { List lists = // new ArrayList<>(); // 会有并发问题 // new Vector<>(); new CopyOnWriteArrayList<>(); // 事件监听器的队列 Random r = new Random(); Thread[] threads = new Thread[100]; for (int i=0; it.start()); Arrays.asList(threads).forEach(t->{ try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); long end = System.currentTimeMillis(); System.out.println(end - start); } } ================================================ FILE: src/main/java/com/mark/concurrent25/T03_SynchronizedList.java ================================================ package com.mark.concurrent25; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @author MarkShen */ public class T03_SynchronizedList { public static void main(String[] args) { List strings = new ArrayList(); // 加锁的容器 List strsSync = Collections.synchronizedList(strings); } } ================================================ FILE: src/main/java/com/mark/concurrent25/T04_ConcurrentQueue.java ================================================ package com.mark.concurrent25; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; /** * 重点内容,重点掌握 * @author MarkShen */ public class T04_ConcurrentQueue { public static void main(String[] args) { Queue strs = new ConcurrentLinkedQueue<>(); // 无界队列 for (int i=0; i<10; i++) { strs.offer("a" + i); } System.out.println(strs); System.out.println(strs.poll()); System.out.println(strs.size()); System.out.println(strs.peek()); System.out.println(strs.size()); // 双端队列 Deque // 并发容器中常用 } } ================================================ FILE: src/main/java/com/mark/concurrent25/T05_LinkedBlockingQueue.java ================================================ package com.mark.concurrent25; import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; /** * 非常常用 * Queue分两种: * * @author MarkShen */ public class T05_LinkedBlockingQueue { static BlockingQueue strs = new LinkedBlockingQueue<>(); // 非常常用, 无界队列 static Random r = new Random(); public static void main(String[] args) { new Thread(() -> { for (int i=0; i<100; i++) { try { strs.put("a" + i); // 如果满了,等会儿 TimeUnit.MICROSECONDS.sleep(r.nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } }, "p1").start(); for (int i = 0; i < 5; i ++) { new Thread(() -> { for (;;) { try { System.out.println(Thread.currentThread().getName() + " take - " + strs.take()); // 如果空了,等待 } catch (InterruptedException e) { e.printStackTrace(); } } }, "c1").start(); } } } ================================================ FILE: src/main/java/com/mark/concurrent25/T06_ArrayBlockingQueue.java ================================================ package com.mark.concurrent25; import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; /** * * @author MarkShen */ public class T06_ArrayBlockingQueue { static BlockingQueue strs = new ArrayBlockingQueue<>(10); // 有界队列, 线程池里装的都是一个一个的任务 static Random r = new Random(); public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { strs.put("a" + i); } // strs.put("aaa"); // 满了就等待 strs.add("aaa"); // strs.offer("aaa"); // strs.offer("aaa", 1, TimeUnit.SECONDS); // 按时间段阻塞 System.out.println(strs); } } ================================================ FILE: src/main/java/com/mark/concurrent25/T07_DelayQueue.java ================================================ package com.mark.concurrent25; import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; /** * 用于执行定时任务 * @author MarkShen */ public class T07_DelayQueue { // 排好顺序的,等待时间最长的被先拿出去 static BlockingQueue tasks = new DelayQueue<>(); // 无界队列, 线程池里装的都是一个一个的任务 static Random r = new Random(); static class MyTask implements Delayed { long runningTime; public MyTask(long runningTime) { this.runningTime = runningTime; } @Override public int compareTo(Delayed o) { if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) { return -1; } else if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) { return 1; } return 0; } @Override public long getDelay(TimeUnit unit) { return unit.convert(runningTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); } @Override public String toString() { return "MyTask [runningTime=" + runningTime + "]"; } } public static void main(String[] args) throws InterruptedException { long now = System.currentTimeMillis(); MyTask t1 = new MyTask(now + 1000); MyTask t2 = new MyTask(now + 2000); MyTask t3 = new MyTask(now + 1500); MyTask t4 = new MyTask(now + 2500); MyTask t5 = new MyTask(now + 500); tasks.put(t1); tasks.put(t2); tasks.put(t3); tasks.put(t4); tasks.put(t5); System.out.println(tasks); for (int i = 0; i < 5; i ++) { System.out.println(tasks.take()); } } } ================================================ FILE: src/main/java/com/mark/concurrent25/T08_TransferQueue.java ================================================ package com.mark.concurrent25; import java.util.concurrent.LinkedTransferQueue; /** * 用在更高的并发的情况下,实时消息处理 * 消费者先起来, 生产者直接找消费者, 如果有消费者,直接把数据给消费者 * * 1) 先启动消费者线程 * 2) 先启动生产者线程 * @author MarkShen */ public class T08_TransferQueue { public static void main(String[] args) throws InterruptedException { LinkedTransferQueue strs = new LinkedTransferQueue<>(); // 先启动消费者线程 new Thread(() -> { try { System.out.println(strs.take()); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); strs.transfer("aaa"); // strs.add("aaa"); // strs.offer("aaa"); // strs.put("aaa"); // 后启动消费者线程会发生阻塞 // new Thread(() -> { // try { // System.out.println(strs.take()); // } catch (InterruptedException e) { // e.printStackTrace(); // } // }).start(); } } ================================================ FILE: src/main/java/com/mark/concurrent25/T09_SynchronousQueue.java ================================================ package com.mark.concurrent25; import java.util.concurrent.BlockingQueue; import java.util.concurrent.SynchronousQueue; /** * @author MarkShen */ public class T09_SynchronousQueue { public static void main(String[] args) throws InterruptedException { // 特殊的TransferQueue, 没有容量的Queue, 容量为0。 BlockingQueue strs = new SynchronousQueue<>(); // 没有容量的队列 new Thread(() -> { try { System.out.println(strs.take()); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); // strs.add("aaa"); strs.put("aaa"); // 阻塞等待消费者消费 System.out.println(strs.size()); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T01_MyExecutor.java ================================================ package com.mark.concurrent26; import java.util.concurrent.Executor; /** * Executor接口 * @author MarkShen */ public class T01_MyExecutor implements Executor { @Override public void execute(Runnable command) { // new Thread(command).run(); command.run(); } public static void main(String[] args) { new T01_MyExecutor().execute(() -> System.out.println("hello executor")); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T02_ExecutorService.java ================================================ package com.mark.concurrent26; /** * ExecutorService 接口 * @author MarkShen */ public class T02_ExecutorService { } ================================================ FILE: src/main/java/com/mark/concurrent26/T03_Callable.java ================================================ package com.mark.concurrent26; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * 注意与Runnable的区别 * https://blog.csdn.net/qq_27258799/article/details/51451143 * https://www.cnblogs.com/frinder6/p/5507082.html * @author MarkShen */ public class T03_Callable implements Callable { private String acceptStr; public T03_Callable(String acceptStr) { this.acceptStr = acceptStr; } @Override public String call() throws Exception { // 任务阻塞 1 秒 Thread.sleep(1000); return this.acceptStr + " append some chars and return it!"; // return null; } public static void main(String[] args) throws Exception { Callable callable = new T03_Callable("my callable test!"); FutureTask task = new FutureTask<>(callable); long beginTime = System.currentTimeMillis(); // 创建线程 new Thread(task).start(); // 调用get()阻塞主线程,反之,线程不会阻塞 String result = task.get(); long endTime = System.currentTimeMillis(); System.out.println("hello : " + result); System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!"); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T04_Executors.java ================================================ package com.mark.concurrent26; /** * 类似设计的类 * Arrays * Collections * Executors * * @author MarkShen */ public class T04_Executors { public static void main(String[] args) { } } ================================================ FILE: src/main/java/com/mark/concurrent26/T05_ThreadPool.java ================================================ package com.mark.concurrent26; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 固定线程个数的线程池 * @author MarkShen */ public class T05_ThreadPool { public static void main(String[] args) throws InterruptedException { // 固定的 ExecutorService service = Executors.newFixedThreadPool(9); for (int i = 1; i <= 10; i ++) { service.execute(()->{ try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); }); } System.out.println(service); // 关闭线程池 service.shutdown(); System.out.println(service.isTerminated()); System.out.println(service.isShutdown()); System.out.println(service); TimeUnit.SECONDS.sleep(5); System.out.println(service.isTerminated()); System.out.println(service.isShutdown()); System.out.println(service); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T06_Future.java ================================================ package com.mark.concurrent26; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; /** * @author MarkShen */ public class T06_Future { public static void main(String[] args) throws InterruptedException, ExecutionException { FutureTask task = new FutureTask<>(() -> { TimeUnit.MILLISECONDS.sleep(500); return 1000; }); // new Callable() {Integer call();} new Thread(task).start(); System.out.println(task.get()); // 阻塞 // *************************** ExecutorService service = Executors.newFixedThreadPool(5); Future f = service.submit(() -> { TimeUnit.MILLISECONDS.sleep(500); return 1; }); System.out.println(f.get()); // System.out.println(f.isDone()); // 结束线程 // service.shutdown(); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T07_ParallelComputing.java ================================================ package com.mark.concurrent26; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * 线程池:并行计算 * @author MarkShen */ public class T07_ParallelComputing { public static void main(String[] args) throws InterruptedException, ExecutionException { long start = System.currentTimeMillis(); List results = getPrime(1, 200000); long end = System.currentTimeMillis(); System.out.println(end - start); // 获取线程核心数 final int cpuCoreNum = Runtime.getRuntime().availableProcessors(); ExecutorService service = Executors.newFixedThreadPool(cpuCoreNum + 1); // 为什么不平均分呢? 跟素数计算有关系 MyTask t1 = new MyTask(1, 80000); MyTask t2 = new MyTask(80001, 130000); MyTask t3 = new MyTask(130001, 170000); MyTask t4 = new MyTask(170001, 200000); Future> f1 = service.submit(t1); Future> f2 = service.submit(t2); Future> f3 = service.submit(t3); Future> f4 = service.submit(t4); start = System.currentTimeMillis(); f1.get(); f2.get(); f3.get(); f4.get(); end = System.currentTimeMillis(); System.out.println(end - start); // 关闭线程池 service.shutdown(); System.out.println(service.isShutdown()); System.out.println(service.isTerminated()); } static List getPrime(int start, int end) { List results = new ArrayList(); for (int i = start; i <= end; i++) { if (isPrime(i)) results.add(i); } return results; } static boolean isPrime(int num) { for (int i = 2; i <= num; i++) { if (num % i == 0) { return false; } } return true; } static class MyTask implements Callable> { int startPos, endPos; public MyTask(int startPos, int endPos) { this.startPos = startPos; this.endPos = endPos; } @Override public List call() throws Exception { List r = getPrime(startPos, endPos); return r; } } } ================================================ FILE: src/main/java/com/mark/concurrent26/T08_CachedThreadPool.java ================================================ package com.mark.concurrent26; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 刚开始一个线程也没有,来个任务起个线程。如果来个任务,线程池中有空闲的,直接使用空闲的线程。 * 线程池中空闲线程空闲超过60s后,线程会自动消失。 * @author MarkShen */ public class T08_CachedThreadPool { public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newCachedThreadPool(); System.out.println(service); for (int i = 0; i < 2; i ++) { service.execute(() -> { try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); }); } System.out.println(service); TimeUnit.SECONDS.sleep(80); System.out.println(service); service.shutdown(); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T09_SingleThreadPool.java ================================================ package com.mark.concurrent26; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 保证任务执行前后顺序 线程池中只有一个线程 * * @author MarkShen */ public class T09_SingleThreadPool { public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newSingleThreadExecutor(); for (int i = 0; i < 5; i++) { final int j = i; service.execute(() -> { System.out.println(j + " " + Thread.currentThread().getName()); }); } System.out.println(service.isTerminated()); service.shutdown(); System.out.println(service.isShutdown()); System.out.println(service.isTerminated()); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T10_ScheduleThreadPool.java ================================================ package com.mark.concurrent26; import java.util.Random; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 定时任务线程池 * @author MarkShen */ public class T10_ScheduleThreadPool { public static void main(String[] args) throws InterruptedException { ScheduledExecutorService service = Executors.newScheduledThreadPool(4); service.scheduleAtFixedRate(()->{ try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); }, 0, 500, TimeUnit.MILLISECONDS); } } ================================================ FILE: src/main/java/com/mark/concurrent26/T11_WorkStealingPool.java ================================================ package com.mark.concurrent26; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 自己找活干的线程 * @author MarkShen */ public class T11_WorkStealingPool { public static void main(String[] args) throws InterruptedException, IOException { // 根据CPU有几核启动多少个默认的线程 // 主动找活儿干; 守护线程,虚拟机不退出,线程不退出。 ExecutorService service = Executors.newWorkStealingPool(); System.out.println(Runtime.getRuntime().availableProcessors()); // 8核处理器 service.execute(new R(1000)); service.execute(new R(2000)); service.execute(new R(2000)); service.execute(new R(2000)); service.execute(new R(2000)); service.execute(new R(2000)); service.execute(new R(2000)); service.execute(new R(2000)); service.execute(new R(2000)); // 由于WorkStealingPool是守护线程(Daemon Thread), 主线程不阻塞,看不到输出 System.in.read(); } static class R implements Runnable { int time; public R(int time) { this.time = time; } @Override public void run() { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } } } ================================================ FILE: src/main/java/com/mark/concurrent26/T12_ForkJoinPool.java ================================================ package com.mark.concurrent26; import java.io.IOException; import java.util.Arrays; import java.util.Random; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; import java.util.concurrent.RecursiveTask; /** * ForkJoin非常经典的算法 * * https://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/index.html * 使用场景:大规模数据计算 * 思路:多线程排序 * @author MarkShen */ public class T12_ForkJoinPool { static int[] nums = new int[1000000]; static final int MAX_NUM = 50000; static Random r = new Random(); static { for (int i = 0; i < nums.length; i ++) { nums[i] = r.nextInt(100); } System.out.println(Arrays.stream(nums).sum()); } static class AddTask extends RecursiveAction { int start, end; public AddTask(int start, int end) { this.start = start; this.end = end; } @Override protected void compute() { if (end - start <= MAX_NUM) { long sum = 0L; for(int i=start; i strs = new ArrayList<>(); strs.add("a"); strs.add("b"); strs.add("c"); strs.add("d"); strs.add("f"); strs.add("g"); // 01 for (int i = 0; i < strs.size(); i++) { System.out.println(strs.get(i)); } // 02 for (String str : strs) { System.out.println(str); } // 03 Iterator it = strs.iterator(); while (it.hasNext()) { System.out.println(it.next()); } // 04 strs.stream().forEach(s -> System.out.println(s)); // 集合遍历方法之 Map Map map = new HashMap<>(); map.put("a", "a"); map.put("b", "b"); map.put("c", "c"); map.put("d", "d"); // 01 for (Map.Entry entry : map.entrySet()) { String mapKey = entry.getKey(); String mapValue = entry.getValue(); System.out.println(mapKey + ":" + mapValue); } // 02 Iterator> entries = map.entrySet().iterator(); while (entries.hasNext()) { Entry entry = entries.next(); String key = entry.getKey(); String value = entry.getValue(); System.out.println(key + ":" + value); } } } ================================================ FILE: src/main/java/com/program/ConstructTree.java ================================================ package com.program; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import com.alibaba.fastjson.JSON; /** * 树形结构遍历 * * @author MarkShen * @Date 2021-02-25 */ public class ConstructTree { static class Menu { private int id; private String name; private int pId; private List menu; public Menu(int id, String name, int pId) { this.id = id; this.name = name; this.pId = pId; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getpId() { return pId; } public void setpId(int pId) { this.pId = pId; } public List getMenu() { return menu; } public void setMenu(List menu) { this.menu = menu; } @Override public String toString() { return "Menu{" + "id=" + id + ", name='" + name + '\'' + ", pId=" + pId + ", menu=" + menu + '}'; } } public static void main(String[] args) { List menus = new ArrayList<>(); menus.add(new Menu(1, "菜单管理", 0)); menus.add(new Menu(2, "系统管理", 1)); menus.add(new Menu(3, "用户管理", 2)); menus.add(new Menu(4, "机构管理", 2)); menus.add(new Menu(5, "权限管理", 2)); menus.add(new Menu(6, "角色管理", 2)); menus.add(new Menu(7, "货物管理", 1)); menus.add(new Menu(8, "仓库管理", 1)); // 获取父节点 List collect = menus.stream().filter(m -> m.getpId() == 0).map((m) -> { m.setMenu(getChildrens(m, menus)); return m; }).collect(Collectors.toList()); System.out.println("-------转json输出结果-------"); System.out.println(JSON.toJSON(collect)); } /** * 递归查询子节点 * * @param root * 根节点 * @param all * 所有节点 * @return 根节点信息 */ private static List getChildrens(Menu root, List all) { List children = all.stream().filter(m -> Objects.equals(m.getpId(), root.getId())).map((m) -> { m.setMenu(getChildrens(m, all)); return m; }).collect(Collectors.toList()); return children; } } ================================================ FILE: src/main/java/com/program/FizzBuzzDemo.java ================================================ package com.program; /** * 编写一个程序:把1-100的数字打印出来。不过,要把3的倍数打印成Bizz,把5的倍数打印成Buzz, 而这个数字 既是3的倍数又是5的倍数,就打成Bizz-Buzz。 */ public class FizzBuzzDemo { public static void main(String[] args) { for (int i = 1; i <= 100; i++) { if (i % 3 == 0 && i % 5 != 0) { System.out.print(" Bizz "); } else if (i % 3 != 0 && i % 5 == 0) { System.out.print(" Buzz "); } else if (i % 3 == 0 && i % 5 == 0) { System.out.print(" Bizz-Buzz "); } else { System.out.print(" " + i + " "); } } } } ================================================ FILE: src/main/java/com/program/ULIDTest.java ================================================ package com.program; import java.util.concurrent.ThreadLocalRandom; import io.azam.ulidj.ULID; /** * https://github.com/ulid/spec */ public class ULIDTest { public static void main(String[] args) { System.out.println("ULID...."); String ulid1 = ULID.random(); String ulid2 = ULID.random(ThreadLocalRandom.current()); System.out.println(ulid1); System.out.println(ulid2); } } ================================================ FILE: src/main/java/com/program/WechatCircleLikeDisplay.java ================================================ package com.program; import java.util.ArrayList; import java.util.List; /** * 微信朋友圈点赞显示 * * @author MarkShen * @since 20210506 */ public class WechatCircleLikeDisplay { private static final String COMMA = ","; public static void main(String[] args) { // Bob, Mark, Mike List names = new ArrayList<>(); names.add("Bob"); names.add("Mark"); names.add("Mike"); System.out.println(getWechatLikeStr(names)); } private static String getWechatLikeStr(List names) { if (names == null || names.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < names.size(); i++) { if (i == 0) { sb.append(names.get(i)); } else { sb.append(COMMA).append(names.get(i)); } } return sb.toString(); } } ================================================ FILE: src/main/java/com/snake/Direction.java ================================================ package com.snake; /** * 方向 */ public enum Direction { LEFT, UP, RIGHT, DOWN } ================================================ FILE: src/main/java/com/snake/Egg.java ================================================ package com.snake; import java.awt.*; import java.util.Random; /** * 蛇食物位置 */ public class Egg { int row, col; Random r = new Random(); public Egg(int row, int col) { this.row = row; this.col = col; } public void paint(Graphics g) { int x = Yard.x + col * Yard.NODE_SIZE; int y = Yard.y + row * Yard.NODE_SIZE; Color c = g.getColor(); g.setColor(Color.RED); g.fillOval(x, y, Yard.NODE_SIZE, Yard.NODE_SIZE); // 恢复现场 g.setColor(c); } public void reAppear() { this.row = r.nextInt(Yard.NODE_COUNT); this.col = r.nextInt(Yard.NODE_COUNT); } } ================================================ FILE: src/main/java/com/snake/Node.java ================================================ package com.snake; import java.awt.*; /** * 双向链表 */ public class Node { int row, col; Node pre, next; public Node(int row, int col) { this.row = row; this.col = col; } public void paint(Graphics g) { int x = Yard.x + col * Yard.NODE_SIZE; int y = Yard.y + row * Yard.NODE_SIZE; Color c = g.getColor(); g.setColor(Color.GREEN); g.fillRect(x, y, Yard.NODE_SIZE, Yard.NODE_SIZE); // 恢复现场 g.setColor(c); } } ================================================ FILE: src/main/java/com/snake/Snake.java ================================================ package com.snake; import java.awt.*; import java.awt.event.KeyEvent; public class Snake { Node head, tail; Direction dir = Direction.LEFT; public Snake() { // initialize snake head = new Node(20, 20); tail = head; } /** * 画出自己(面向对象的思维) * @param g */ public void paint(Graphics g) { Node n = head; while (n != null) { n.paint(g); n = n.next; } move(); } private void move() { addToHead(); deleteTail(); boundaryCheck(); } private void boundaryCheck() { if (head.row < 0) head.row = Yard.NODE_COUNT - 1; if (head.col < 0) head.col = Yard.NODE_COUNT - 1; if (head.row > Yard.NODE_COUNT - 1) head.row = 0; if (head.col < Yard.NODE_COUNT - 1) head.col = 0; } private void addToHead() { Node n = null; switch (dir) { case LEFT: n = new Node(head.row, head.col - 1); break; case RIGHT: n = new Node(head.row, head.col + 1); break; case UP: n = new Node(head.row - 1, head.col); break; case DOWN: n = new Node(head.row + 1, head.col); break; } // add new snake head n.next = head; head.pre = n; head = n; } private void deleteTail() { if (tail == null) return; tail = tail.pre; tail.next.pre = null; // 不加这句话,会有内存泄漏的风险 tail.next = null; } /** * 判断用户按下那个键 * @param e */ public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_LEFT: dir = Direction.LEFT; break; case KeyEvent.VK_RIGHT: dir = Direction.RIGHT; break; case KeyEvent.VK_UP: dir = Direction.UP; break; case KeyEvent.VK_DOWN: dir = Direction.DOWN; break; } } public void eat(Egg e) { if (head.row == e.row && head.col == e.col) { addToHead(); e.reAppear(); } } } ================================================ FILE: src/main/java/com/snake/Yard.java ================================================ package com.snake; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class Yard extends Frame { public static final int NODE_SIZE = 15; // 格子大小 public static final int NODE_COUNT = 30; // 格子数量 public static final int AREA_WIDTH = NODE_SIZE * NODE_COUNT; // 格子左上角点的坐标 public static int x = AREA_WIDTH / 2; public static int y = AREA_WIDTH / 2; private Egg e = new Egg(10, 10); private Snake s = new Snake(); public Yard() { this.setSize(2 * AREA_WIDTH, 2 * AREA_WIDTH); this.setVisible(Boolean.TRUE); // 添加关闭按钮事件 this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); this.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { s.keyPressed(e); } }); // repaint while (true) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.repaint(); } } /** * 画出小蛇跑的区域 * @param g */ @Override public void paint(Graphics g) { Color c = g.getColor(); g.setColor(Color.WHITE); g.fillRect(0, 0, this.getWidth(), this.getHeight()); g.setColor(Color.BLACK); for (int i = 0; i <= NODE_COUNT; i ++) { // 画横线 g.drawLine(x, y + NODE_SIZE * i, x + AREA_WIDTH, y + NODE_SIZE * i); // 画纵线 g.drawLine(x + NODE_SIZE * i, y, x + NODE_SIZE * i, y + AREA_WIDTH); } s.paint(g); e.paint(g); s.eat(e); // 保持现场 g.setColor(c); } // 双缓冲 Image offScreenImage = null; @Override public void update(Graphics g) { if (offScreenImage == null) { offScreenImage = this.createImage(this.getWidth(), this.getHeight()); } Graphics gOff = offScreenImage.getGraphics(); print(gOff); g.drawImage(offScreenImage, 0, 0, null); } public static void main(String[] args) { new Yard(); } } ================================================ FILE: src/main/java/com/thread/AnimalBehavior.java ================================================ package com.thread; /** * @author MarkShen */ public interface AnimalBehavior { default void eat() { System.out.println("hello world"); } } ================================================ FILE: src/main/java/com/thread/Cat.java ================================================ package com.thread; /** * @author MarkShen */ public class Cat implements AnimalBehavior { @Override public void eat() { System.out.println("Cat eat..."); } } ================================================ FILE: src/main/java/com/thread/CatMain.java ================================================ package com.thread; /** * @author MarkShen */ public class CatMain { public static void main(String[] args) { AnimalBehavior animalBehavior = new Cat(); animalBehavior.eat(); } } ================================================ FILE: src/main/java/com/thread/MyRunnable.java ================================================ package com.thread; import java.util.concurrent.TimeUnit; /** * @author MarkShen */ public class MyRunnable implements Runnable { @Override public void run() { Thread currentThread = Thread.currentThread(); System.out.println(currentThread.getName() + "-------------进入"); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(currentThread.getName() + "-------------离开"); } } } ================================================ FILE: src/main/java/com/thread/MyRunnableTest.java ================================================ package com.thread; /** * @author MarkShen */ public class MyRunnableTest { public static void main(String[] args) { MyRunnable runnable = new MyRunnable(); Thread thread1 = new Thread(runnable, "线程1"); Thread thread2 = new Thread(runnable, "线程2"); Thread thread3 = new Thread(runnable, "线程3"); thread1.start(); thread2.start(); thread3.start(); } } ================================================ FILE: src/main/java/com/thread/NotifySpecifiedThread.java ================================================ package com.thread; import java.util.concurrent.locks.LockSupport; /** * 唤醒“指定”的某个线程 * * 使用Java6引入了LockSupport这个类 * @author MarkShen */ public class NotifySpecifiedThread { public static void main(String[] args) throws Exception { Thread t = new Thread(()->{ System.out.println("start"); LockSupport.park(); // park可以让当前线程进入wait状态 System.out.println("continue"); }); t.start(); Thread.sleep(1000); LockSupport.unpark(t); // unpark可以解除指定线程的wait态,不需要拥有某个对象的特定锁 } } ================================================ FILE: src/main/java/com/thread/T.java ================================================ package com.thread; public class T { public static void main(String[] args) { int a = 2; switch (a) { case 1: case 2: System.out.println(a); break; default: System.out.println(a + 1); break; } } } ================================================ FILE: src/main/java/com/thread/T01_TestJoin.java ================================================ package com.thread; import java.util.concurrent.TimeUnit; public class T01_TestJoin { public static void main(String[] args) { Thread t1 = new Thread(new MyThread(), "t1"); Thread t2 = new Thread(new MyThread(), "t2"); try { // Waits for this thread to die. t2.join(0); } catch (InterruptedException e) { e.printStackTrace(); } t1.start(); t2.start(); } } class MyThread implements Runnable { @Override public void run() { // 线程通信 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } } ================================================ FILE: src/test/java/com/java8/NewFeatureTest.java ================================================ package com.java8; import junit.framework.TestCase; import org.junit.Test; import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream; /** * Java 8 New feature test */ public class NewFeatureTest extends TestCase { @Test public void testLambda01() { // () -> 3.14 // (value) -> (value % 2) == 0 // Lambda 表达式是匿名内部类的一种简化 MyVal myVal = () -> 3.14; System.out.println(myVal.getVal()); ValidEvenNum validEvenNum = (value) -> (value % 2) == 0; System.out.println(validEvenNum.isEven(10)); } @Test public void testLambda02() { MyVal myVal = new MyVal() { @Override public double getVal() { return 3.14; } }; System.out.println(myVal.getVal()); } @Test public void testLambda03() { // Lambda 表达式和匿名内部类的应用,字符串的逆序输出 之 // IN: abcdefg OUT: gfedcba display("abcdefg", new MyFunctionalInterface() { @Override public String reverse(String s) { StringBuilder sb = new StringBuilder(); char[] chars = s.toCharArray(); for (int i = chars.length - 1; i >= 0; i--) { sb.append(chars[i]); } return sb.toString(); } }); } @Test public void testLambda04() { // Lambda 表达式和匿名内部类的应用,字符串的逆序输出 之 // IN: abcdefg OUT: gfedcba display("abcdefg", (s) -> { StringBuilder sb = new StringBuilder(); char[] chars = s.toCharArray(); for (int i = chars.length - 1; i >= 0; i--) { sb.append(chars[i]); } return sb.toString(); }); } public void display(String s, MyFunctionalInterface myFunctionalInterface) { System.out.println(myFunctionalInterface.reverse(s)); } interface MyFunctionalInterface { String reverse(String s); } interface MyVal { double getVal(); } interface ValidEvenNum { boolean isEven(int num); } // =============================================================== // https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/ @Test public void testLambda05() { // 1. Individual values Stream stream = Stream.of("a", "b", "c"); stream.forEach(System.out::print); System.out.println(); // 2. Arrays String [] strArray = new String[] {"a", "b", "c"}; stream = Stream.of(strArray); stream.forEach(System.out::print); System.out.println(); stream = Arrays.stream(strArray); stream.forEach(System.out::print); System.out.println(); // 3. Collections List list = Arrays.asList(strArray); stream = list.stream(); stream.forEach(System.out::print); } /** * 数值流的构造 */ @Test public void testLambda06() { IntStream.of(new int[]{1, 2, 3}).forEach(System.out::print); System.out.println(); IntStream.range(1, 3).forEach(System.out::print); System.out.println(); IntStream.rangeClosed(1, 3).forEach(System.out::print); } } ================================================ FILE: src/test/java/com/mark/concurrent01/TTest.java ================================================ package com.mark.concurrent01; import junit.framework.TestCase; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.time.Instant; /** * Unit test for simple App. */ public class TTest extends TestCase { @Before public void setUp() throws Exception {} @After public void tearDown() throws Exception {} @Test public void testM() { T t = new T(); new Thread(() -> t.m(), "t1").start(); new Thread(() -> t.m(), "t2").start(); } @Test public void testDate() { // 46546544654.666 // way 01 Long currentTime = System.currentTimeMillis(); String currentTimeWay01 = currentTime / 1000L + "." + currentTime % 1000L; System.out.println(currentTimeWay01); // way 02 Instant instant = Instant.now(); System.out.println(instant); System.out.println(instant.getEpochSecond()); // 秒数 System.out.println(instant.toEpochMilli()); // 毫秒 System.out.println(System.currentTimeMillis()); // 毫秒 } } ================================================ FILE: style/STYLE.md ================================================ ## 统一代码风格 如果要编辑本项目,一定要统一代码风格 ### 统一方案 本工程代码遵守阿里巴巴[p3c](https://github.com/alibaba/p3c)规范,在代码开发前建议: * 安装阿里巴巴规约插件,用于提早发现不规范代码,具体安装方法参照:[p3c](https://github.com/alibaba/p3c),里面有eclipse,idea的安装方法 * 安装codeStyle插件,用于格式化代码的时候符合代码规范,安装方法见:[安装codeStyle插件](#codeStyleInstall) * checkStyle校验,这个不用安装,`mvn`在编译的时候自己会调用,写在`pom.xml`里,用`maven-pmd-plugin`调用`pmd-p3c`规范校验 如果工作中遇到代码格式化问题,经常导致git冲突,也可以采用上面的方案 ### codeStyle插件安装 这里注意下,不管eclipse或者idea,都需要导入eclipse文件夹下面的配置 #### eclipse * 依次点击:`Window->Preferences->Java->Code Style->Formatter->Import` * 选择`style/eclipse/codestyle.xml`文件 确定 * 默认在`Active profile`中选择新导入的`P3C-CodeStyle`,如未选择,请手动选择 * 点击`Apply`完成配置 ![step](../img/style/eclipse/step.jpg) #### idea * 依次点击进入插件界面:`File->Settings->Plugins`,搜索 eclipse code formatter,如已有插件则不需安装,如没有,点击Search in repositories自动搜索线上插件。 ![step1](../img/style/idea/step1.png) * 导入`style/eclipse/codestyle.xml` 这里记住用的也是eclipse里面的 点击OK ![step1](../img/style/idea/step2.png) * 依次点击进入插件界面:`File->Settings->Editor->Code Style->Java->Import Scheme->Intellij IDEA code style XML`,导入`style/idea/codestyle.xml` 这里用的是idea的配置文件 ![step1](../img/style/idea/step3.png) * 完成 ### 附 #### windows系统,代码规范校验提示乱码 这个是因为cmd默认gbk,cmd输入:`CHCP 65001` 在运行mvn 提示就是不会乱码了 ================================================ FILE: style/codestyle/eclipse/codestyle.xml ================================================ ================================================ FILE: style/codestyle/idea/codestyle.xml ================================================ ================================================ FILE: test/test.txt ================================================ 思考题 1. A线程正在执行一个对象中的同步方法, B线程是否可以同时执行同一个对象中的非同步方法? 2. 同上,B线程是否可以同时执行同一个对象中的另一个同步方法? 3. 线程抛出异常会释放锁吗? 4. volatile和synchronized区别? 可见性, 原子性(synchronized), 可见性(volatile) 5. 写一程序证明, AtomXXX类比synchronized更有效. 6. AtomXXX类可以保证可见性吗?请写一个程序证明. 7. 写一个程序证明AtomXXX类的多个方法并不构成原子性. 8. 写一程序模拟死锁 9. 写一个程序, 在main线程中启动100个线程,100个线程完成后,主线程打印完成, 使用join()和countDownLatch都可以完成。 10. 一个高效的游戏服务器应该如何设计其架构。 11. ReentrantLock与synchronized的区别 12. 消息的可靠性和幂等 共享资源读写的时候需要线程同步。 线程同步方式:1)共享内存; 2)发消息