From dda1ee067b92f426078223e5effb1ab7ee6b2585 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Mon, 9 Jul 2018 11:35:37 +0800 Subject: [PATCH 01/14] =?UTF-8?q?HashMap=E4=B8=AD=E7=9A=84Hash=E7=A2=B0?= =?UTF-8?q?=E6=92=9E=E6=98=AF=E7=94=B1=E4=BA=8Ekey=E7=9A=84hashCode?= =?UTF-8?q?=E5=92=8C=E5=B7=B2=E5=AD=98=E5=9C=A8=E7=9A=84hashCode=E7=9B=B8?= =?UTF-8?q?=E5=90=8C=E5=AF=BC=E8=87=B4=E7=A2=B0=E6=92=9E=E3=80=82=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=8A=9E=E6=B3=95=E6=9C=89=E6=8B=89=E9=93=BE=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=86=8Dhash=E6=B3=95=E7=AD=89=E7=AD=89=E5=87=A0?= =?UTF-8?q?=E7=A7=8D=E6=96=B9=E6=B3=95=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/facetoface/HashCrash.java | 58 +++++++++++++++++++ src/main/java/facetoface/HashMapKeyOnOne.java | 12 ++++ 2 files changed, 70 insertions(+) create mode 100644 src/main/java/facetoface/HashCrash.java create mode 100644 src/main/java/facetoface/HashMapKeyOnOne.java diff --git a/src/main/java/facetoface/HashCrash.java b/src/main/java/facetoface/HashCrash.java new file mode 100644 index 0000000..7e53bb8 --- /dev/null +++ b/src/main/java/facetoface/HashCrash.java @@ -0,0 +1,58 @@ +package facetoface; + +import java.util.HashMap; + +public class HashCrash { + public static void main(String[] args) { + HashMap hash = new HashMap(); + Long start = System.currentTimeMillis(); + System.out.println("-----one begin-----"); + for (Integer i = 0; i < 1231; i++) { + App app = new App(); + app.setId(100); + hash.put(app, i.toString()); + } + App app2 = new App(); + app2.setId(100); + hash.get(app2); + Long end = System.currentTimeMillis(); + System.out.println("第一种方式" + (end - start) / 1000);//33 + System.out.println("-----two begin-----"); + HashMap hash2 = new HashMap<>(); + Long start2 = System.currentTimeMillis(); + for (Integer i = 0; i < 65536; i++) { + App app = new App(); + app.setId(i); + hash2.put(app, i.toString()); + } + App app3 = new App(); + app3.setId(100); + hash2.get(app3); + Long end2 = System.currentTimeMillis(); + System.out.println("第2种方式" + (end2 - start2) / 1000); + } +} + +class App { + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Override + public boolean equals(Object obj) { + // TODO Auto-generated method stub + return super.equals(obj); + } + + @Override + public int hashCode() { + // TODO Auto-generated method stub + return id; + } +} diff --git a/src/main/java/facetoface/HashMapKeyOnOne.java b/src/main/java/facetoface/HashMapKeyOnOne.java new file mode 100644 index 0000000..1d5a81e --- /dev/null +++ b/src/main/java/facetoface/HashMapKeyOnOne.java @@ -0,0 +1,12 @@ +package facetoface; + +import java.util.HashMap; + +public class HashMapKeyOnOne { + public static void main(String[] args) { + int h; + String key = ""; + int hashCode= (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); + System.out.println(hashCode); + } +} -- Gitee From 74ef5050df3c3900312cd9365df9cf08edfee91c Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Thu, 12 Jul 2018 10:49:11 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E5=8D=95=E4=BE=8B=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E6=87=92=E6=B1=89=E6=A8=A1=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E9=A5=BF=E6=B1=89=E6=A8=A1=E5=BC=8F=EF=BC=8C=E6=8C=87=E5=AE=9A?= =?UTF-8?q?map=E5=AE=B9=E5=99=A8=E6=9A=82=E5=AD=98=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E8=8E=B7=E5=BE=97=E6=8C=87=E5=AE=9A=E5=8D=95=E5=88=A9=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E7=AD=89=E7=AD=89=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/lynn/haveObject/ListIter.java | 3 -- .../DoubleCheckedLockingSingleTon.java | 32 +++++++++++++++ .../java/design/singleton/LazySingleTon.java | 33 +++++++++++++++ .../java/design/singleton/MapSingleTon.java | 40 +++++++++++++++++++ .../design/singleton/StarveSingleTon.java | 23 +++++++++++ src/test/java/demo/CollectionTest.java | 39 ++++++++++++++++++ 6 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 src/main/java/design/singleton/DoubleCheckedLockingSingleTon.java create mode 100644 src/main/java/design/singleton/LazySingleTon.java create mode 100644 src/main/java/design/singleton/MapSingleTon.java create mode 100644 src/main/java/design/singleton/StarveSingleTon.java create mode 100644 src/test/java/demo/CollectionTest.java diff --git a/src/main/java/com/lynn/haveObject/ListIter.java b/src/main/java/com/lynn/haveObject/ListIter.java index c0761a8..d1d2c1c 100644 --- a/src/main/java/com/lynn/haveObject/ListIter.java +++ b/src/main/java/com/lynn/haveObject/ListIter.java @@ -14,7 +14,4 @@ public class ListIter { System.out.println(listIterator.next() + "," + listIterator.nextIndex() + "," + listIterator.previousIndex()); } } - - class Pet { - } } diff --git a/src/main/java/design/singleton/DoubleCheckedLockingSingleTon.java b/src/main/java/design/singleton/DoubleCheckedLockingSingleTon.java new file mode 100644 index 0000000..833e52d --- /dev/null +++ b/src/main/java/design/singleton/DoubleCheckedLockingSingleTon.java @@ -0,0 +1,32 @@ +package design.singleton; + +/** + * 双检锁/双重校验锁(DCL,即 double-checked locking) + * 特点:懒汉式的改进版,Lazy初始化;线程安全,且在多线程情况下能保持高性能 + */ +public class DoubleCheckedLockingSingleTon { + private static DoubleCheckedLockingSingleTon singleTon; + + private DoubleCheckedLockingSingleTon() { + + } + + public static DoubleCheckedLockingSingleTon getSingleTon() { + if (singleTon == null) { + synchronized (DoubleCheckedLockingSingleTon.class) { + if (singleTon == null) { + singleTon = new DoubleCheckedLockingSingleTon(); + } + } + } + return singleTon; + } + + public static void main(String[] args) { + if (DoubleCheckedLockingSingleTon.getSingleTon().hashCode() == DoubleCheckedLockingSingleTon.getSingleTon().hashCode()) {//三种方式都是比较对象的地址层次递进 + System.out.println("DoubleCheckedLockingSingleTonOne == DoubleCheckedLockingSingleTonTwo"); + } else { + System.out.println("DoubleCheckedLockingSingleTonOne != DoubleCheckedLockingSingleTonTwo"); + } + } +} diff --git a/src/main/java/design/singleton/LazySingleTon.java b/src/main/java/design/singleton/LazySingleTon.java new file mode 100644 index 0000000..ac3beeb --- /dev/null +++ b/src/main/java/design/singleton/LazySingleTon.java @@ -0,0 +1,33 @@ +package design.singleton; + +/** + * 懒汉式 + * 特点:Lazy初始化;线程安全,但是由于每次需要同步性能较低,不建议使用 + * 学习网址https://mp.weixin.qq.com/s/jtA0FYbaTBSzSO9NcczdYw + */ +class LazySingleTon { + private static LazySingleTon lazySingleTon; + + private LazySingleTon() { + + } + + public static synchronized LazySingleTon getSingleTon() { + if (lazySingleTon == null) { + lazySingleTon = new LazySingleTon(); + } + return lazySingleTon; + } + + public static void main(String[] args) { +// if (LazySingleTon.getSingleTon().equals(LazySingleTon.getSingleTon())) { +// if (LazySingleTon.getSingleTon() == LazySingleTon.getSingleTon() ) { + if (LazySingleTon.getSingleTon().hashCode() == LazySingleTon.getSingleTon().hashCode()) {//三种方式都是比较对象的地址层次递进 + System.out.println("SingleTonOne == SingleTonTwo"); + } else { + System.out.println("SingleTonOne != SingleTonTwo"); + } + } +} + + diff --git a/src/main/java/design/singleton/MapSingleTon.java b/src/main/java/design/singleton/MapSingleTon.java new file mode 100644 index 0000000..85ac82f --- /dev/null +++ b/src/main/java/design/singleton/MapSingleTon.java @@ -0,0 +1,40 @@ +package design.singleton; + +import java.util.HashMap; +import java.util.Map; + +public class MapSingleTon { + public static class SingletonManager { + + private SingletonManager() { + + } + + private static Map sSingletonMap = new HashMap<>(); + + static void register(String key, MapSingleTon value) { + if (!sSingletonMap.containsKey(key)) { + sSingletonMap.put(key, value); + } + } + + public static void unregister(String key) { + if (sSingletonMap.containsKey(key)) { + sSingletonMap.remove(key); + } + } + + + static MapSingleTon getSingleton(String key) { + return sSingletonMap.get(key); + } + } + + public static void main(String[] args) { + MapSingleTon singleTon = new MapSingleTon(); + int hashOne = singleTon.hashCode(); + MapSingleTon.SingletonManager.register("demo", singleTon); + int hash = MapSingleTon.SingletonManager.getSingleton("demo").hashCode(); + System.out.println(hash == hashOne); + } +} diff --git a/src/main/java/design/singleton/StarveSingleTon.java b/src/main/java/design/singleton/StarveSingleTon.java new file mode 100644 index 0000000..bfa8a04 --- /dev/null +++ b/src/main/java/design/singleton/StarveSingleTon.java @@ -0,0 +1,23 @@ +package design.singleton; + +/** + * 饿汉式 + * 特点:非Lazy初始化,浪费内存;线程安全,基于ClassLoader机制避免了多线程的同步问题 + */ +public class StarveSingleTon { + //方式一:类装载的时候初始化 + private static StarveSingleTon singleTon = new StarveSingleTon(); + + //方式二:类初始化的时候才去初始化 +// static { +// singleTon = new StarveSingleTon(); +// } + + private StarveSingleTon() { + + } + + public static synchronized StarveSingleTon getSingleTon() { + return singleTon; + } +} diff --git a/src/test/java/demo/CollectionTest.java b/src/test/java/demo/CollectionTest.java new file mode 100644 index 0000000..d53dbab --- /dev/null +++ b/src/test/java/demo/CollectionTest.java @@ -0,0 +1,39 @@ +package demo; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; + +public class CollectionTest { + @Test + public void collection() { + Collection collection = new HashSet<>(); + collection.add("1"); + collection.add("2"); + System.out.println(collection); + System.out.println(collection.toArray() instanceof Object[]); + } + //若ArrayList中要添加大量元素,则使用ensureCapacity(int n)方法一次性增加,可优化运行效率 + @Test + public void arrayList() { + ArrayList list = new ArrayList<>(); + final int N =10000000; + long startTime = System.currentTimeMillis(); + for(int i = 0;i(); + long startTime1 = System.currentTimeMillis(); + list.ensureCapacity(N); + for(int i = 0;i Date: Thu, 12 Jul 2018 11:44:37 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E5=B7=A5=E5=8E=82=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=8F=8D=E5=B0=84=E8=8E=B7=E5=BE=97=E5=AE=9E?= =?UTF-8?q?=E4=BE=8B=E5=AF=B9=E8=B1=A1=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/design/factory/Client.java | 10 +++++++++ .../java/design/factory/ConcreateFactory.java | 14 +++++++++++++ src/main/java/design/factory/Factory.java | 5 +++++ src/main/java/design/factory/Product.java | 21 +++++++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 src/main/java/design/factory/Client.java create mode 100644 src/main/java/design/factory/ConcreateFactory.java create mode 100644 src/main/java/design/factory/Factory.java create mode 100644 src/main/java/design/factory/Product.java diff --git a/src/main/java/design/factory/Client.java b/src/main/java/design/factory/Client.java new file mode 100644 index 0000000..39f12ec --- /dev/null +++ b/src/main/java/design/factory/Client.java @@ -0,0 +1,10 @@ +package design.factory; +/**https://mp.weixin.qq.com/s?__biz=MzIwNDU0MDg3Ng==&mid=2247483979&idx=1&sn=f08f551153174bffac2d96f7c31e0478&chksm=973fdce8a04855fe134b07124b08a7ed2dbca052885961c5201631b9e754473b1d97a9aada13&scene=0#rd + * */ +public class Client { + public static void main(String[] args) { + ConcreateFactory factory = new ConcreateFactory(); + factory.create(FastFood.class).sell(); + factory.create(HealthProduct.class).sell(); + } +} diff --git a/src/main/java/design/factory/ConcreateFactory.java b/src/main/java/design/factory/ConcreateFactory.java new file mode 100644 index 0000000..67db85d --- /dev/null +++ b/src/main/java/design/factory/ConcreateFactory.java @@ -0,0 +1,14 @@ +package design.factory; + +public class ConcreateFactory extends Factory { + @Override + T create(Class clz) { + Product product = null; + try { + product = (Product) Class.forName(clz.getName()).newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + return (T) product; + } +} diff --git a/src/main/java/design/factory/Factory.java b/src/main/java/design/factory/Factory.java new file mode 100644 index 0000000..6d3a104 --- /dev/null +++ b/src/main/java/design/factory/Factory.java @@ -0,0 +1,5 @@ +package design.factory; + +abstract class Factory { + abstract T create(Class clz); +} diff --git a/src/main/java/design/factory/Product.java b/src/main/java/design/factory/Product.java new file mode 100644 index 0000000..8897529 --- /dev/null +++ b/src/main/java/design/factory/Product.java @@ -0,0 +1,21 @@ +package design.factory; + +abstract class Product { + abstract void sell(); +} + +class FastFood extends Product { + + @Override + void sell() { + System.out.println("快餐出售"); + } +} + +class HealthProduct extends Product { + + @Override + void sell() { + System.out.println("保健品出售"); + } +} -- Gitee From 015cba2711de371ea78de920553a95d205319621 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Thu, 12 Jul 2018 13:35:05 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E9=80=9A=E8=BF=87=E5=8F=8D=E5=B0=84=E8=8E=B7?= =?UTF-8?q?=E5=BE=97=E5=AE=9E=E4=BE=8B=E5=AF=B9=E8=B1=A1=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../factory/abstractFactory/Client.java | 7 ++++ .../abstractFactory/ConcreteFactory1.java | 38 +++++++++++++++++++ .../factory/abstractFactory/Factory.java | 7 ++++ .../factory/abstractFactory/ProductB.java | 24 ++++++++++++ .../design/factory/{ => simple}/Client.java | 2 +- .../{ => simple}/ConcreateFactory.java | 2 +- .../design/factory/{ => simple}/Factory.java | 2 +- .../design/factory/{ => simple}/Product.java | 2 +- 8 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/main/java/design/factory/abstractFactory/Client.java create mode 100644 src/main/java/design/factory/abstractFactory/ConcreteFactory1.java create mode 100644 src/main/java/design/factory/abstractFactory/Factory.java create mode 100644 src/main/java/design/factory/abstractFactory/ProductB.java rename src/main/java/design/factory/{ => simple}/Client.java (93%) rename src/main/java/design/factory/{ => simple}/ConcreateFactory.java (91%) rename src/main/java/design/factory/{ => simple}/Factory.java (73%) rename src/main/java/design/factory/{ => simple}/Product.java (90%) diff --git a/src/main/java/design/factory/abstractFactory/Client.java b/src/main/java/design/factory/abstractFactory/Client.java new file mode 100644 index 0000000..8d767c4 --- /dev/null +++ b/src/main/java/design/factory/abstractFactory/Client.java @@ -0,0 +1,7 @@ +package design.factory.abstractFactory; + +public class Client { + public static void main(String[] args) { + + } +} diff --git a/src/main/java/design/factory/abstractFactory/ConcreteFactory1.java b/src/main/java/design/factory/abstractFactory/ConcreteFactory1.java new file mode 100644 index 0000000..1d961ed --- /dev/null +++ b/src/main/java/design/factory/abstractFactory/ConcreteFactory1.java @@ -0,0 +1,38 @@ +package design.factory.abstractFactory; + +public class ConcreteFactory1 extends Factory { + @Override + public ConcreateProductA1 createProductA() { + return new ConcreateProductA1(); + } + + @Override + public ConcreateProductB1 createProductB() { + return new ConcreateProductB1(); + } +} + +class ConcreteFactory2 extends Factory { + @Override + public ConcreateProductA2 createProductA() { + return new ConcreateProductA2(); + } + + @Override + public ConcreateProductB2 createProductB() { + return new ConcreateProductB2(); + } +} + + +class ConcreateProductA1 extends ProductA { +} + +class ConcreateProductB1 extends ProductB { +} + +class ConcreateProductA2 extends ProductA { +} + +class ConcreateProductB2 extends ProductB { +} diff --git a/src/main/java/design/factory/abstractFactory/Factory.java b/src/main/java/design/factory/abstractFactory/Factory.java new file mode 100644 index 0000000..a935cc1 --- /dev/null +++ b/src/main/java/design/factory/abstractFactory/Factory.java @@ -0,0 +1,7 @@ +package design.factory.abstractFactory; + +public abstract class Factory { + public abstract ProductA createProductA(); + + public abstract ProductB createProductB(); +} diff --git a/src/main/java/design/factory/abstractFactory/ProductB.java b/src/main/java/design/factory/abstractFactory/ProductB.java new file mode 100644 index 0000000..8ec0671 --- /dev/null +++ b/src/main/java/design/factory/abstractFactory/ProductB.java @@ -0,0 +1,24 @@ +package design.factory.abstractFactory; + +abstract class ProductB { +} + +class Product1 extends ProductB { + +} + +class Product3 extends ProductA { + +} + +class Product2 extends ProductB { + +} + +class Product14 extends ProductA { + +} + +abstract class ProductA { + +} diff --git a/src/main/java/design/factory/Client.java b/src/main/java/design/factory/simple/Client.java similarity index 93% rename from src/main/java/design/factory/Client.java rename to src/main/java/design/factory/simple/Client.java index 39f12ec..312bfce 100644 --- a/src/main/java/design/factory/Client.java +++ b/src/main/java/design/factory/simple/Client.java @@ -1,4 +1,4 @@ -package design.factory; +package design.factory.simple; /**https://mp.weixin.qq.com/s?__biz=MzIwNDU0MDg3Ng==&mid=2247483979&idx=1&sn=f08f551153174bffac2d96f7c31e0478&chksm=973fdce8a04855fe134b07124b08a7ed2dbca052885961c5201631b9e754473b1d97a9aada13&scene=0#rd * */ public class Client { diff --git a/src/main/java/design/factory/ConcreateFactory.java b/src/main/java/design/factory/simple/ConcreateFactory.java similarity index 91% rename from src/main/java/design/factory/ConcreateFactory.java rename to src/main/java/design/factory/simple/ConcreateFactory.java index 67db85d..8bc9455 100644 --- a/src/main/java/design/factory/ConcreateFactory.java +++ b/src/main/java/design/factory/simple/ConcreateFactory.java @@ -1,4 +1,4 @@ -package design.factory; +package design.factory.simple; public class ConcreateFactory extends Factory { @Override diff --git a/src/main/java/design/factory/Factory.java b/src/main/java/design/factory/simple/Factory.java similarity index 73% rename from src/main/java/design/factory/Factory.java rename to src/main/java/design/factory/simple/Factory.java index 6d3a104..1600d21 100644 --- a/src/main/java/design/factory/Factory.java +++ b/src/main/java/design/factory/simple/Factory.java @@ -1,4 +1,4 @@ -package design.factory; +package design.factory.simple; abstract class Factory { abstract T create(Class clz); diff --git a/src/main/java/design/factory/Product.java b/src/main/java/design/factory/simple/Product.java similarity index 90% rename from src/main/java/design/factory/Product.java rename to src/main/java/design/factory/simple/Product.java index 8897529..2409120 100644 --- a/src/main/java/design/factory/Product.java +++ b/src/main/java/design/factory/simple/Product.java @@ -1,4 +1,4 @@ -package design.factory; +package design.factory.simple; abstract class Product { abstract void sell(); -- Gitee From 03e32314f04ccacfbbc69df228dd2ab9f1ce7174 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Fri, 13 Jul 2018 10:43:20 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E5=BB=BA=E9=80=A0=E5=99=A8=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/design/builder/Builder.java | 44 +++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/java/design/builder/Builder.java diff --git a/src/main/java/design/builder/Builder.java b/src/main/java/design/builder/Builder.java new file mode 100644 index 0000000..63c2a2c --- /dev/null +++ b/src/main/java/design/builder/Builder.java @@ -0,0 +1,44 @@ +package design.builder; + +public class Builder { +} + +class Product { + private String mPartA; + private String mPartB; + private String mPartC; + + private static class Builder { + Product mProduct; + + public Builder() { + this.mProduct = new Product(); + } + + public Builder builderA(String mPartA) { + mProduct.mPartA = mPartA; + return this; + } + + public Builder builderB(String mPartB) { + mProduct.mPartB = mPartB; + return this; + } + + public Builder builderC(String mPartC) { + mProduct.mPartC = mPartC; + return this; + } + + public Product build() { + return mProduct; + } + } + + public static void main(String[] args) { + Product product = new Product.Builder().builderA("PartA").builderB("PartB").builderC("PartC").build(); + System.out.println(product.mPartA); + System.out.println(product.mPartB); + System.out.println(product.mPartC); + } +} -- Gitee From 5c72a86e0eeb9c2f1c56b376ae1e54e1ee20af6f Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Fri, 13 Jul 2018 14:23:24 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E9=80=82=E9=85=8D=E5=99=A8=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E5=92=8C=E4=BB=A3=E7=90=86=E6=A8=A1=E5=BC=8F!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/design/adapter/Adaptee.java | 19 +++++++++++++++++++ src/main/java/design/adapter/Adapter.java | 12 ++++++++++++ src/main/java/design/adapter/Client.java | 11 +++++++++++ .../{com/lynn => design}/factory/Games.java | 2 +- .../typeinfo => design/proxy}/ProxyCglib.java | 2 +- .../typeinfo => design/proxy}/ProxyJdk.java | 6 +----- .../proxy}/ProxyStatic.java | 2 +- 7 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 src/main/java/design/adapter/Adaptee.java create mode 100644 src/main/java/design/adapter/Adapter.java create mode 100644 src/main/java/design/adapter/Client.java rename src/main/java/{com/lynn => design}/factory/Games.java (97%) rename src/main/java/{com/lynn/typeinfo => design/proxy}/ProxyCglib.java (97%) rename src/main/java/{com/lynn/typeinfo => design/proxy}/ProxyJdk.java (90%) rename src/main/java/{com/lynn/typeinfo => design/proxy}/ProxyStatic.java (97%) diff --git a/src/main/java/design/adapter/Adaptee.java b/src/main/java/design/adapter/Adaptee.java new file mode 100644 index 0000000..4ffb8c1 --- /dev/null +++ b/src/main/java/design/adapter/Adaptee.java @@ -0,0 +1,19 @@ +package design.adapter; + +public class Adaptee { + //原有的业务逻辑 + public void volt220() { + System.out.println("220V电压"); + } +} + +interface Target { + void volt5(); +} + +class ConcreteTarget implements Target { + @Override + public void volt5() { + System.out.println("5V电压"); + } +} diff --git a/src/main/java/design/adapter/Adapter.java b/src/main/java/design/adapter/Adapter.java new file mode 100644 index 0000000..56c4931 --- /dev/null +++ b/src/main/java/design/adapter/Adapter.java @@ -0,0 +1,12 @@ +package design.adapter; + +public class Adapter extends Adaptee implements Target { + @Override + public void volt5() { + System.out.println("5V电压"); + } + + public void volt220() { + super.volt220(); + } +} diff --git a/src/main/java/design/adapter/Client.java b/src/main/java/design/adapter/Client.java new file mode 100644 index 0000000..508a43c --- /dev/null +++ b/src/main/java/design/adapter/Client.java @@ -0,0 +1,11 @@ +package design.adapter; + +public class Client { + public static void main(String[] args) { + Target t1 = new ConcreteTarget(); + t1.volt5(); + + Target t2 = new Adapter(); + t2.volt5(); + } +} diff --git a/src/main/java/com/lynn/factory/Games.java b/src/main/java/design/factory/Games.java similarity index 97% rename from src/main/java/com/lynn/factory/Games.java rename to src/main/java/design/factory/Games.java index 7a25099..6cd3fdf 100644 --- a/src/main/java/com/lynn/factory/Games.java +++ b/src/main/java/design/factory/Games.java @@ -1,4 +1,4 @@ -package com.lynn.factory; +package design.factory; public class Games { public static void main(String[] args) { diff --git a/src/main/java/com/lynn/typeinfo/ProxyCglib.java b/src/main/java/design/proxy/ProxyCglib.java similarity index 97% rename from src/main/java/com/lynn/typeinfo/ProxyCglib.java rename to src/main/java/design/proxy/ProxyCglib.java index 2eea1c6..2081ea4 100644 --- a/src/main/java/com/lynn/typeinfo/ProxyCglib.java +++ b/src/main/java/design/proxy/ProxyCglib.java @@ -1,4 +1,4 @@ -package com.lynn.typeinfo; +package design.proxy; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; diff --git a/src/main/java/com/lynn/typeinfo/ProxyJdk.java b/src/main/java/design/proxy/ProxyJdk.java similarity index 90% rename from src/main/java/com/lynn/typeinfo/ProxyJdk.java rename to src/main/java/design/proxy/ProxyJdk.java index 39b4c64..55fd073 100644 --- a/src/main/java/com/lynn/typeinfo/ProxyJdk.java +++ b/src/main/java/design/proxy/ProxyJdk.java @@ -1,11 +1,7 @@ -package com.lynn.typeinfo; +package design.proxy; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import com.lynn.typeinfo.ProxyCglib; - /** * JDK代理 也是动态代理 */ diff --git a/src/main/java/com/lynn/typeinfo/ProxyStatic.java b/src/main/java/design/proxy/ProxyStatic.java similarity index 97% rename from src/main/java/com/lynn/typeinfo/ProxyStatic.java rename to src/main/java/design/proxy/ProxyStatic.java index 2d69f06..9f3c727 100644 --- a/src/main/java/com/lynn/typeinfo/ProxyStatic.java +++ b/src/main/java/design/proxy/ProxyStatic.java @@ -1,4 +1,4 @@ -package com.lynn.typeinfo; +package design.proxy; /** * 静态代理 -- Gitee From af70481cd41e263f91f392c445074848f3721bff Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Tue, 31 Jul 2018 12:27:40 +0800 Subject: [PATCH 07/14] =?UTF-8?q?ooo=EF=BC=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/design/builder/Builder.java | 10 +-- .../java/leetcode/ListTotal/ListAndArray.java | 45 ++++++++++++++ src/test/java/demo/MapTest.java | 31 ++++++++++ src/test/java/demo/ThreadTest.java | 61 +++++++++++++++++++ 4 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 src/main/java/leetcode/ListTotal/ListAndArray.java create mode 100644 src/test/java/demo/MapTest.java create mode 100644 src/test/java/demo/ThreadTest.java diff --git a/src/main/java/design/builder/Builder.java b/src/main/java/design/builder/Builder.java index 63c2a2c..c804d35 100644 --- a/src/main/java/design/builder/Builder.java +++ b/src/main/java/design/builder/Builder.java @@ -11,26 +11,26 @@ class Product { private static class Builder { Product mProduct; - public Builder() { + Builder() { this.mProduct = new Product(); } - public Builder builderA(String mPartA) { + Builder builderA(String mPartA) { mProduct.mPartA = mPartA; return this; } - public Builder builderB(String mPartB) { + Builder builderB(String mPartB) { mProduct.mPartB = mPartB; return this; } - public Builder builderC(String mPartC) { + Builder builderC(String mPartC) { mProduct.mPartC = mPartC; return this; } - public Product build() { + Product build() { return mProduct; } } diff --git a/src/main/java/leetcode/ListTotal/ListAndArray.java b/src/main/java/leetcode/ListTotal/ListAndArray.java new file mode 100644 index 0000000..9a06144 --- /dev/null +++ b/src/main/java/leetcode/ListTotal/ListAndArray.java @@ -0,0 +1,45 @@ +package leetcode.ListTotal; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +// +public class ListAndArray { + @Test + public void testThreeSum() { + int[] nums = {-1, 0, 1, 2, -1, -4,4,7,0};//{-1,0,1},{-1,2,-1}} + System.out.println(threeSum(nums)); + } + + /**例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], + * 满足要求的三元组集合为:[[-1, 0, 1],[-1, -1, 2]] + * */ + public List> threeSum(int[] nums) { + List> listTotal = new ArrayList>(); + List list = null; + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + for (int k = j + 1; k < nums.length; k++) { + if ((nums[i] + nums[j] + nums[k]) == 0) { + list = new ArrayList<>(); + list.add(nums[i]); + list.add(nums[j]); + list.add(nums[k]); + list.sort(new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o1.compareTo(o2); + } + }); + if (!listTotal.contains(list)) { + listTotal.add(list); + } + } + } + } + } + return listTotal; + } +} diff --git a/src/test/java/demo/MapTest.java b/src/test/java/demo/MapTest.java new file mode 100644 index 0000000..5e6c558 --- /dev/null +++ b/src/test/java/demo/MapTest.java @@ -0,0 +1,31 @@ +package demo; + +import org.junit.jupiter.api.Test; + +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.Map; + +public class MapTest { + @Test + public void testMap() { + HashMap integerStringHashMap = new HashMap<>(); + integerStringHashMap.put(1, "zhangkai"); + integerStringHashMap.put(2, "wq"); + integerStringHashMap.put(3, "kj"); + HashMap integerStringHashMap1 = new HashMap<>(integerStringHashMap); + System.out.println(integerStringHashMap); + System.out.println(integerStringHashMap1); + integerStringHashMap.put(3, "kjj"); + System.out.println(integerStringHashMap); + System.out.println(integerStringHashMap1); + integerStringHashMap1.put(3, "kjjjjjj"); + System.out.println(integerStringHashMap); + System.out.println(integerStringHashMap1); + integerStringHashMap.remove(3); + System.out.println(integerStringHashMap); + System.out.println(integerStringHashMap1); + System.out.println(integerStringHashMap.hashCode()); + System.out.println(integerStringHashMap1.hashCode()); + } +} diff --git a/src/test/java/demo/ThreadTest.java b/src/test/java/demo/ThreadTest.java new file mode 100644 index 0000000..4ca0aa3 --- /dev/null +++ b/src/test/java/demo/ThreadTest.java @@ -0,0 +1,61 @@ +package demo; + +import org.junit.jupiter.api.Test; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ThreadTest { + @Test + public void test01() { + ExecutorService service = Executors.newCachedThreadPool(); // 创建一个线程池 + for (int i = 0; i < 100; i++) { + Runnable runnable = () -> { + try { + System.out.println(Thread.currentThread().getName() + ":" + DateUtil.parse("2017-06-24 06:02:20")); + Thread.sleep(30000); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + }; + service.execute(runnable);// 为线程池添加任务 + } + } +} + +class DateUtil { + private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public static String formatDate(Date date) throws ParseException { + synchronized (sdf) { + return sdf.format(date); + } + } + + public static Date parse(String strDate) throws ParseException { + synchronized (sdf) { + return sdf.parse(strDate); + } + } +} +class ConcurrentDateUtil { + + private static ThreadLocal threadLocal = new ThreadLocal() { + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; + + public static Date parse(String dateStr) throws ParseException { + return threadLocal.get().parse(dateStr); + } + + public static String format(Date date) { + return threadLocal.get().format(date); + } +} -- Gitee From 4da6b51c542b3dd986481146ef97ef93dab3f6c9 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Tue, 31 Jul 2018 14:25:09 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E8=A7=A3=E6=9E=90=E6=BA=90=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=E6=B5=8B=E8=AF=95!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/jdk18/function/FunctionTest.java | 10 ++ .../java/leetcode/ListTotal/ListAndArray.java | 9 +- .../leetcode/ListTotal/SingleLinkedList.java | 130 ++++++++++++++++++ src/test/java/demo/MapTest.java | 3 + src/test/java/demo/StringBuilderTest.java | 16 +++ 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 src/main/java/jdk18/function/FunctionTest.java create mode 100644 src/main/java/leetcode/ListTotal/SingleLinkedList.java create mode 100644 src/test/java/demo/StringBuilderTest.java diff --git a/src/main/java/jdk18/function/FunctionTest.java b/src/main/java/jdk18/function/FunctionTest.java new file mode 100644 index 0000000..d081cba --- /dev/null +++ b/src/main/java/jdk18/function/FunctionTest.java @@ -0,0 +1,10 @@ +package jdk18.function18.function; + +import java.util.function.Function; + +class FunctionTest{ + public static void main(String[] args) { + Function sqrt = input -> Math.sqrt(input); + System.out.println(sqrt.apply(4.0)); + } +} diff --git a/src/main/java/leetcode/ListTotal/ListAndArray.java b/src/main/java/leetcode/ListTotal/ListAndArray.java index 9a06144..547f022 100644 --- a/src/main/java/leetcode/ListTotal/ListAndArray.java +++ b/src/main/java/leetcode/ListTotal/ListAndArray.java @@ -4,18 +4,21 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Comparator; +import java.util.LinkedList; import java.util.List; + // public class ListAndArray { @Test public void testThreeSum() { - int[] nums = {-1, 0, 1, 2, -1, -4,4,7,0};//{-1,0,1},{-1,2,-1}} + int[] nums = {-1, 0, 1, 2, -1, -4, 4, 7, 0};//{-1,0,1},{-1,2,-1}} System.out.println(threeSum(nums)); } - /**例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], + /** + * 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], * 满足要求的三元组集合为:[[-1, 0, 1],[-1, -1, 2]] - * */ + */ public List> threeSum(int[] nums) { List> listTotal = new ArrayList>(); List list = null; diff --git a/src/main/java/leetcode/ListTotal/SingleLinkedList.java b/src/main/java/leetcode/ListTotal/SingleLinkedList.java new file mode 100644 index 0000000..76a27c8 --- /dev/null +++ b/src/main/java/leetcode/ListTotal/SingleLinkedList.java @@ -0,0 +1,130 @@ +package leetcode.ListTotal; + +import org.junit.jupiter.api.Test; + +public class SingleLinkedList { + private int size;//链表节点的个数 + private Node head;//头节点 + + public SingleLinkedList() { + size = 0; + head = null; + } + + //链表的每个节点类 + private class Node { + private Object data;//每个节点的数据 + private Node next;//每个节点指向下一个节点的连接 + + public Node(Object data) { + this.data = data; + } + } + + //在链表头添加元素 + public Object addHead(Object obj) { + Node newHead = new Node(obj); + if (size == 0) { + head = newHead; + } else { + newHead.next = head; + head = newHead; + } + size++; + return obj; + } + + //在链表头删除元素 + public Object deleteHead() { + Object obj = head.data; + head = head.next; + size--; + return obj; + } + + //查找指定元素,找到了返回节点Node,找不到返回null + public Node find(Object obj) { + Node current = head; + int tempSize = size; + while (tempSize > 0) { + if (obj.equals(current.data)) { + return current; + } else { + current = current.next; + } + tempSize--; + } + return null; + } + + //删除指定的元素,删除成功返回true + public boolean delete(Object value) { + if (size == 0) { + return false; + } + Node current = head; + Node previous = head; + while (current.data != value) { + if (current.next == null) { + return false; + } else { + previous = current; + current = current.next; + } + } + //如果删除的节点是第一个节点 + if (current == head) { + head = current.next; + size--; + } else {//删除的节点不是第一个节点 + previous.next = current.next; + size--; + } + return true; + } + + //判断链表是否为空 + public boolean isEmpty() { + return (size == 0); + } + + //显示节点信息 + public void display() { + if (size > 0) { + Node node = head; + int tempSize = size; + if (tempSize == 1) {//当前链表只有一个节点 + System.out.println("[" + node.data + "]"); + return; + } + while (tempSize > 0) { + if (node.equals(head)) { + System.out.print("[" + node.data + "->"); + } else if (node.next == null) { + System.out.print(node.data + "]"); + } else { + System.out.print(node.data + "->"); + } + node = node.next; + tempSize--; + } + System.out.println(); + } else {//如果链表一个节点都没有,直接打印[] + System.out.println("[]"); + } + + } + + @Test + void main() { + SingleLinkedList linkedList = new SingleLinkedList(); + linkedList.addHead('1'); + linkedList.addHead('2'); + linkedList.addHead('3'); + linkedList.display(); + System.out.println(linkedList.find('1')); + System.out.println(linkedList.find('2')); + System.out.println(linkedList.find('3')); + System.out.println(linkedList.size); + } +} diff --git a/src/test/java/demo/MapTest.java b/src/test/java/demo/MapTest.java index 5e6c558..de06b75 100644 --- a/src/test/java/demo/MapTest.java +++ b/src/test/java/demo/MapTest.java @@ -27,5 +27,8 @@ public class MapTest { System.out.println(integerStringHashMap1); System.out.println(integerStringHashMap.hashCode()); System.out.println(integerStringHashMap1.hashCode()); + System.out.println(integerStringHashMap.getOrDefault(8, "zhangkai")); + System.out.println(integerStringHashMap.putIfAbsent(8, "zhangkai")); + System.out.println(integerStringHashMap); } } diff --git a/src/test/java/demo/StringBuilderTest.java b/src/test/java/demo/StringBuilderTest.java new file mode 100644 index 0000000..7de15fa --- /dev/null +++ b/src/test/java/demo/StringBuilderTest.java @@ -0,0 +1,16 @@ +package demo; + +import org.junit.jupiter.api.Test; + +public class StringBuilderTest { + @Test + public void testStringBuild() { + StringBuilder stringBuilder = new StringBuilder("zhangk"); + stringBuilder.appendCodePoint(97); + stringBuilder.append('i'); + System.out.println(stringBuilder.toString()); + char a[] = {97}; + stringBuilder.insert(4, a); + System.out.println(stringBuilder.toString()); + } +} -- Gitee From 1d39293b834b4f565ab05ea871426d2127b4b909 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Thu, 2 Aug 2018 14:34:01 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B=E7=9A=84?= =?UTF-8?q?=E7=8E=A9=E6=84=8F!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Maven__com_alibaba_fastjson_1_2_47.xml | 13 ++++ ...Maven__org_projectlombok_lombok_1_18_2.xml | 13 ++++ .idea/thinkJava.iml | 2 + pom.xml | 16 +++- src/main/java/thread/ChoujiangTest.java | 36 +++++++++ src/main/java/thread/ThreadLocalPro.java | 44 +++++++++++ src/main/java/thread/ThreadTest.java | 77 +++++++++++++++++++ src/main/resources/package.json | 10 +++ src/main/resources/package2.json | 10 +++ 9 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 .idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml create mode 100644 .idea/libraries/Maven__org_projectlombok_lombok_1_18_2.xml create mode 100644 src/main/java/thread/ChoujiangTest.java create mode 100644 src/main/java/thread/ThreadLocalPro.java create mode 100644 src/main/java/thread/ThreadTest.java create mode 100644 src/main/resources/package.json create mode 100644 src/main/resources/package2.json diff --git a/.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml b/.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml new file mode 100644 index 0000000..dcd6ee5 --- /dev/null +++ b/.idea/libraries/Maven__com_alibaba_fastjson_1_2_47.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_projectlombok_lombok_1_18_2.xml b/.idea/libraries/Maven__org_projectlombok_lombok_1_18_2.xml new file mode 100644 index 0000000..638f01b --- /dev/null +++ b/.idea/libraries/Maven__org_projectlombok_lombok_1_18_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/thinkJava.iml b/.idea/thinkJava.iml index f146ff1..d9d5bfc 100644 --- a/.idea/thinkJava.iml +++ b/.idea/thinkJava.iml @@ -19,5 +19,7 @@ + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 64be963..0fe40b8 100644 --- a/pom.xml +++ b/pom.xml @@ -13,8 +13,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 @@ -31,6 +31,18 @@ cglib 3.2.6 + + + org.projectlombok + lombok + 1.18.2 + + + + com.alibaba + fastjson + 1.2.47 + diff --git a/src/main/java/thread/ChoujiangTest.java b/src/main/java/thread/ChoujiangTest.java new file mode 100644 index 0000000..4b5ed1b --- /dev/null +++ b/src/main/java/thread/ChoujiangTest.java @@ -0,0 +1,36 @@ +package thread; + +//1.有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池用一个数组int[] arr = {10,5,20,50,100,200,500,800,2,80,300}; +//创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”,随机从arr数组中获取奖项元素并打印在控制台上,格式如下: +public class ChoujiangTest { + public static void main(String[] args) { + new Thread(new Chou(), "抽奖箱1").start(); + new Thread(new Chou(), "抽奖箱2").start(); + } +} + +class Chou implements Runnable { + int arr[] = {10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300}; + int num = arr.length; + boolean[] flag = new boolean[num]; + + @Override + public void run() { + while (true) { + //保证并发 + synchronized (this) { + if (num > 0) { + int index = (int) (Math.random() * arr.length); + int get = arr[index]; + // 代表这张抽奖券抽过了 + if (!flag[index]) { + flag[index] = true; + System.out.println(Thread.currentThread().getName() + " 又产生了一个" + get + "元大奖"); + num--; + } + } + } + } + + } +} diff --git a/src/main/java/thread/ThreadLocalPro.java b/src/main/java/thread/ThreadLocalPro.java new file mode 100644 index 0000000..8cd6568 --- /dev/null +++ b/src/main/java/thread/ThreadLocalPro.java @@ -0,0 +1,44 @@ +package thread; + +import lombok.Data; +import org.junit.jupiter.api.Test; + +public class ThreadLocalPro { + + public void set() { + THREAD_LOCAL.set(man); + } + + @Test + public void testThreadLocal() { + final Thread[] threads = new Thread[5]; + for (int i = 0; i < 5; i++) { + threads[i] = new Thread(new Runnable() { + @Override + public void run() { + set();//初始化或者是initialValue 赋值否则空指针异常 + THREAD_LOCAL.get().setName(THREAD_LOCAL.get().getName() + "+"); + System.out.println(Thread.currentThread().getName() + ":" + THREAD_LOCAL.get().getName()); + } + }); + } + for (Thread thread : threads) { + thread.start(); + } + } + + private static Man man = new Man(); + private static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>(); +// new ThreadLocal() { +// @Override +// protected Man initialValue() { +// return man; +// } +// }; +//} +} + +@Data +class Man { + String name = "NoName"; +} diff --git a/src/main/java/thread/ThreadTest.java b/src/main/java/thread/ThreadTest.java new file mode 100644 index 0000000..edb783b --- /dev/null +++ b/src/main/java/thread/ThreadTest.java @@ -0,0 +1,77 @@ +package thread; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ThreadTest { + public static void main(String[] args) throws InterruptedException { + //一个线程去读取两个文件 + long start = System.currentTimeMillis(); + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + try { + System.out.println("json文件读取完成①:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); + + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + Thread thread1 = new Thread(new Runnable() { + @Override + public void run() { + try { + System.out.println("json文件读取完成②:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.execute(thread); + executorService.execute(thread1); + + executorService.shutdown(); + while (true) { + if (executorService.isTerminated()) { + long endTime = System.currentTimeMillis(); + System.out.println("程序结束了,总耗时:" + String.valueOf(endTime - start) + " ms(毫秒)!\n"); + break; + } + } + + new Thread(new Runnable() { + @Override + public void run() { + try { + long start = System.currentTimeMillis(); + System.out.println("json文件读取完成①:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); + System.out.println("json文件读取完成②:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); + long stop = System.currentTimeMillis(); + System.out.println("程序结束了,总耗时:" + String.valueOf(stop - start) + " ms(毫秒)!\n"); + } catch (IOException e) { + e.printStackTrace(); + } + } + }).start(); + } + + static StringBuilder readFileSync(String fileName) throws IOException { + File file = new File(fileName); + InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file)); + BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + StringBuilder sb = new StringBuilder("{"); + while (null != bufferedReader.readLine()) { + sb.append(bufferedReader.readLine()); + } + sb.append("}"); + return sb; + } +} diff --git a/src/main/resources/package.json b/src/main/resources/package.json new file mode 100644 index 0000000..65021ea --- /dev/null +++ b/src/main/resources/package.json @@ -0,0 +1,10 @@ +{ + "name": "koa2-lynn", + "version": "0.0.1", + "private": false, + "scripts": {}, + "dependencies": { + "https": "^1.0.0", + "koa2": "^2.0.0-alpha.7" + } +} diff --git a/src/main/resources/package2.json b/src/main/resources/package2.json new file mode 100644 index 0000000..65021ea --- /dev/null +++ b/src/main/resources/package2.json @@ -0,0 +1,10 @@ +{ + "name": "koa2-lynn", + "version": "0.0.1", + "private": false, + "scripts": {}, + "dependencies": { + "https": "^1.0.0", + "koa2": "^2.0.0-alpha.7" + } +} -- Gitee From ccaafa95107b539a6352068f47a10bac8ade30c9 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Thu, 2 Aug 2018 15:35:33 +0800 Subject: [PATCH 10/14] =?UTF-8?q?leetCode=E7=9A=84=E7=8E=A9=E6=84=8F!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/leetcode/array/ArrayAri.java | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/leetcode/array/ArrayAri.java diff --git a/src/main/java/leetcode/array/ArrayAri.java b/src/main/java/leetcode/array/ArrayAri.java new file mode 100644 index 0000000..cb683e3 --- /dev/null +++ b/src/main/java/leetcode/array/ArrayAri.java @@ -0,0 +1,30 @@ +package leetcode.array; +/** + * 给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。 + *我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。 + *如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。 + * */ +public class ArrayAri { + public static int pivotIndex(int[] nums) { + for (int i = 0; i < nums.length; i++) { + int a = 0; + int b = 0; + for (int j = 0; j < i; j++) { + a += nums[j]; + } + for (int t = i; t < nums.length; t++) { + b += nums[t]; + } + if (a == b) { + return i; + } + } + return 0; + } + + public static void main(String[] args) { +// int[] nums = {1, 1, -1, 3, 3, 1, -1, 1};//test1 + int[] nums = {1, 7, 3, 6, 5}; + System.out.println(pivotIndex(nums)); + } +} -- Gitee From 9845132ffc79ea1ea55f51a50163a4d2c96c9398 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Thu, 2 Aug 2018 16:32:52 +0800 Subject: [PATCH 11/14] ooo --- src/main/java/leetcode/MainClass.java | 52 ++++++++++++++++++++++ src/main/java/leetcode/array/ArrayAri.java | 13 +++--- src/main/java/leetcode/array/ArrayMax.java | 41 +++++++++++++++++ 3 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/main/java/leetcode/MainClass.java create mode 100644 src/main/java/leetcode/array/ArrayMax.java diff --git a/src/main/java/leetcode/MainClass.java b/src/main/java/leetcode/MainClass.java new file mode 100644 index 0000000..3a07f3b --- /dev/null +++ b/src/main/java/leetcode/MainClass.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +class Solution { + public static int pivotIndex(int[] nums) { + for (int i = 0; i < nums.length; i++) { + int a = 0; + int b = 0; + for (int j = 0; j < i; j++) { + a += nums[j]; + } + for (int t = i + 1; t < nums.length; t++) { + b += nums[t]; + } + if (a == b) { + return i; + } + } + return 0; + } +} + +public class MainClass { + public static int[] stringToIntegerArray(String input) { + input = input.trim(); + input = input.substring(1, input.length() - 1); + if (input.length() == 0) { + return new int[0]; + } + String[] parts = input.split(","); + int[] output = new int[parts.length]; + for(int index = 0; index < parts.length; index++) { + String part = parts[index].trim(); + output[index] = Integer.parseInt(part); + } + return output; + } + + public static void main(String[] args) throws IOException { + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + String line; + while ((line = in.readLine()) != null) { + int[] nums = stringToIntegerArray(line); + int ret = new Solution().pivotIndex(nums); + String out = String.valueOf(ret); + System.out.print(out); + } + } +} diff --git a/src/main/java/leetcode/array/ArrayAri.java b/src/main/java/leetcode/array/ArrayAri.java index cb683e3..7fbe2b7 100644 --- a/src/main/java/leetcode/array/ArrayAri.java +++ b/src/main/java/leetcode/array/ArrayAri.java @@ -1,9 +1,10 @@ package leetcode.array; + /** * 给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。 - *我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。 - *如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。 - * */ + * 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。 + * 如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。 + */ public class ArrayAri { public static int pivotIndex(int[] nums) { for (int i = 0; i < nums.length; i++) { @@ -12,7 +13,7 @@ public class ArrayAri { for (int j = 0; j < i; j++) { a += nums[j]; } - for (int t = i; t < nums.length; t++) { + for (int t = i + 1; t < nums.length; t++) { b += nums[t]; } if (a == b) { @@ -23,8 +24,8 @@ public class ArrayAri { } public static void main(String[] args) { -// int[] nums = {1, 1, -1, 3, 3, 1, -1, 1};//test1 - int[] nums = {1, 7, 3, 6, 5}; + int[] nums = {1, 1, -1, 1, 3, 1, 1, -1, 1};//test1 +// int[] nums = {1, 7, 3, 6, 5, 6}; System.out.println(pivotIndex(nums)); } } diff --git a/src/main/java/leetcode/array/ArrayMax.java b/src/main/java/leetcode/array/ArrayMax.java new file mode 100644 index 0000000..8118a94 --- /dev/null +++ b/src/main/java/leetcode/array/ArrayMax.java @@ -0,0 +1,41 @@ +package leetcode.array; + +/** + * 在一个给定的数组nums中,总是存在一个最大元素 。 + * 查找数组中的最大元素是否至少是数组中每个其他数字的两倍。 + * 如果是,则返回最大元素的索引,否则返回-1。 + */ +public class ArrayMax { + public static void main(String[] args) { + int[] nums = {0, 0, 4, 0, 1, 9, 3}; +// int[] nums = {1, 2, 3, 4}; + System.out.println(new Solution().dominantIndex(nums)); + } +} + +class Solution { + public int dominantIndex(int[] nums) { + int index = 0; + int max = nums[0]; + for (int i = 0; i < nums.length - 1; i++) { + if (max > nums[i + 1]) { + index = i; + } else { + max = nums[i + 1]; + index = i + 1; + } + } + int j = 0; + while (j < nums.length) { + if (index == j) { + break; + } + if (max < 2 * nums[j]) { + System.out.println(j); + return -1; + } + j++; + } + return index; + } +} -- Gitee From 7f9cf125e8b9cfcdf94b08dc2561576afbfcf3c5 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Fri, 3 Aug 2018 13:45:23 +0800 Subject: [PATCH 12/14] =?UTF-8?q?juc=E5=A4=9A=E7=BA=BF=E7=A8=8B=E5=AD=A6?= =?UTF-8?q?=E4=B9=A0=E7=9A=84=E4=B8=80=E5=A0=86!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/thread/juc/cas/AtomicDemo.java | 44 +++++++++++++++++++ .../thread/juc/volatilePro/VolatieTest.java | 39 ++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 src/main/java/thread/juc/cas/AtomicDemo.java create mode 100644 src/main/java/thread/juc/volatilePro/VolatieTest.java diff --git a/src/main/java/thread/juc/cas/AtomicDemo.java b/src/main/java/thread/juc/cas/AtomicDemo.java new file mode 100644 index 0000000..8bdf5a6 --- /dev/null +++ b/src/main/java/thread/juc/cas/AtomicDemo.java @@ -0,0 +1,44 @@ +package thread.juc.cas; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 会有多个线程操作同一数据,破坏了原子性 + * 解决办法:jdk1.5 Java.util.cocyrrent.atomic提供了常用的原子变量 + * 1. volatile 保证内存可见性 + * 2 cas(Compare-and-swap) 算法保证数据原子性 : 是对硬件对并发共享数据的支持 + * cas包含了三个操作数 + * 内存值 V + * 预估值 A(旧值) + * 更新值 B + * 当且仅当 V == A 时, V 赋值 B 否则什么都不做! + */ +public class AtomicDemo { + //产生重复数据,原子性问题 + public static void main(String[] args) { + AtomicThread atomicThread = new AtomicThread(); + for (int i = 0; i < 10; i++) { + new Thread(atomicThread).start(); + } + } +} + +class AtomicThread implements Runnable { + //volatile也不能保证共享数据的原子性 +// private int serialNunmber = 0; + private AtomicInteger serialNnmber = new AtomicInteger(); + + @Override + public void run() { + try { + Thread.sleep(200); + System.out.println(Thread.currentThread().getName() + ":" + getSerialNunmber()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public int getSerialNunmber() { + return serialNnmber.getAndIncrement(); + } +} diff --git a/src/main/java/thread/juc/volatilePro/VolatieTest.java b/src/main/java/thread/juc/volatilePro/VolatieTest.java new file mode 100644 index 0000000..9c5e42e --- /dev/null +++ b/src/main/java/thread/juc/volatilePro/VolatieTest.java @@ -0,0 +1,39 @@ +package thread.juc.volatilePro; + +import lombok.Data; +/**volatie 不具有互斥性,不存在抢锁之说! 多个线程可以同时访问 + * 不能保证变量的原子性, + * */ +public class VolatieTest { + public static void main(String[] args) { + Thread thread = new Thread(); + new java.lang.Thread(thread).start(); + while (true) { + //①线程同步,刷新主内存中的数据,但是效率低 +// synchronized (thread) { + if (thread.isFlag()) { + System.out.println("--------------------------"); + break; +// } + } + } + } +} + +@Data +class Thread implements Runnable { + private volatile boolean flag; + //②多线程内共享变量/数据是可见的(实时刷新缓存中的数据) + // private boolean flag; + + @Override + public void run() { + try { + java.lang.Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + flag = true; + System.out.println("flag value is [" + isFlag() + "]"); + } +} -- Gitee From edb83a1d410f7f7c8c9f41142e221abbdbfb1364 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Fri, 3 Aug 2018 14:03:46 +0800 Subject: [PATCH 13/14] =?UTF-8?q?juc=E5=A4=9A=E7=BA=BF=E7=A8=8B=E5=AD=A6?= =?UTF-8?q?=E4=B9=A0=E7=9A=84=E4=B8=80=E5=A0=86!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/thread/juc/cas/CASArithmetic.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/thread/juc/cas/CASArithmetic.java diff --git a/src/main/java/thread/juc/cas/CASArithmetic.java b/src/main/java/thread/juc/cas/CASArithmetic.java new file mode 100644 index 0000000..03a6db9 --- /dev/null +++ b/src/main/java/thread/juc/cas/CASArithmetic.java @@ -0,0 +1,41 @@ +package thread.juc.cas; + +/** + * CAS compare-and-swap算法模拟 + */ +public class CASArithmetic { + public static void main(String[] args) { + final CompareAndSwap cas = new CompareAndSwap(); + for (int i = 0; i < 10; i++) { + new Thread(() -> { + int expectedValue = cas.get(); + boolean b = cas.conpareAndSet(expectedValue, (int)(Math.random() * 101)); + System.out.println(Thread.currentThread().getName() + " : " + b); + }).start(); + } + } +} + +class CompareAndSwap { + private int value; + + public synchronized int get() { + return value; + } + + //比较和替换 + public synchronized int compareAndSwap(int expectedValue, int newValue) { + int oldValue = value; + + if (oldValue == expectedValue) { + this.value = newValue; + } + + return oldValue; + } + + //V == A + public synchronized boolean conpareAndSet(int expectedValue, int newValue) { + return expectedValue == compareAndSwap(expectedValue, newValue); + } +} -- Gitee From 306e6843e2bf545231227d2c110bc4dd297784a5 Mon Sep 17 00:00:00 2001 From: noLynn <13293871521@163.com> Date: Fri, 3 Aug 2018 16:14:40 +0800 Subject: [PATCH 14/14] =?UTF-8?q?juc=E5=A4=9A=E7=BA=BF=E7=A8=8B=E5=AD=A6?= =?UTF-8?q?=E4=B9=A0=E7=9A=84=E4=B8=80=E5=A0=86!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/thread/ThreadTest.java | 123 +++++++++++------- .../concurrent/TestCopyOnWriteArrayList.java | 40 ++++++ .../countdownlatch/TestCountdownlatch.java | 53 ++++++++ 3 files changed, 169 insertions(+), 47 deletions(-) create mode 100644 src/main/java/thread/juc/concurrent/TestCopyOnWriteArrayList.java create mode 100644 src/main/java/thread/juc/countdownlatch/TestCountdownlatch.java diff --git a/src/main/java/thread/ThreadTest.java b/src/main/java/thread/ThreadTest.java index edb783b..79ff657 100644 --- a/src/main/java/thread/ThreadTest.java +++ b/src/main/java/thread/ThreadTest.java @@ -2,68 +2,97 @@ package thread; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import jdk.nashorn.internal.objects.annotations.Constructor; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.RequiredArgsConstructor; import org.junit.jupiter.api.Test; import java.io.*; import java.util.Date; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import static thread.ReadFileThread.readFileSync; + public class ThreadTest { public static void main(String[] args) throws InterruptedException { //一个线程去读取两个文件 + /**单个线程读取多个文件 + * */ + ReadFileThread readFileThread = new ReadFileThread("src/main/resources/package.json", "src/main/resources/package2.json"); + new Thread(readFileThread).start(); + + /**多个线程读取一个文件* */ + CountDownLatch countDownLatch = new CountDownLatch(2); + ReadFileThreadMore readFileThreadMore = new ReadFileThreadMore(countDownLatch, "src/main/resources/package.json"); long start = System.currentTimeMillis(); - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - try { - System.out.println("json文件读取完成①:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); - - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - Thread thread1 = new Thread(new Runnable() { - @Override - public void run() { - try { - System.out.println("json文件读取完成②:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - ExecutorService executorService = Executors.newCachedThreadPool(); - executorService.execute(thread); - executorService.execute(thread1); - - executorService.shutdown(); - while (true) { - if (executorService.isTerminated()) { - long endTime = System.currentTimeMillis(); - System.out.println("程序结束了,总耗时:" + String.valueOf(endTime - start) + " ms(毫秒)!\n"); - break; - } + for (int i = 0; i < 2; i++) { + new Thread(readFileThreadMore).start(); + } + try { + countDownLatch.await();//注掉看效果 + long stop = System.currentTimeMillis(); + System.out.println("程序结束了,总耗时:" + String.valueOf(stop - start) + " ms(毫秒)!\n"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + +} + +@Data +@AllArgsConstructor +class ReadFileThreadMore implements Runnable { + + private CountDownLatch latch; + private String fileName; + + public ReadFileThreadMore() { + } + + public ReadFileThreadMore(CountDownLatch latch) { + this.latch = latch; + } + + @Override + public void run() { + try { + System.out.println("读取文件" + fileName + "完成:" + readFileSync(fileName)); + } catch (IOException e) { + e.printStackTrace(); + } finally { + latch.countDown();//减1 } + } +} + - new Thread(new Runnable() { - @Override - public void run() { - try { - long start = System.currentTimeMillis(); - System.out.println("json文件读取完成①:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); - System.out.println("json文件读取完成②:" + JSON.parseObject(readFileSync("src/main/resources/package.json").toString())); - long stop = System.currentTimeMillis(); - System.out.println("程序结束了,总耗时:" + String.valueOf(stop - start) + " ms(毫秒)!\n"); - } catch (IOException e) { - e.printStackTrace(); - } +@Data +@AllArgsConstructor +class ReadFileThread implements Runnable { + + private String fileName; + private String fileName2; + + @Override + public void run() { + try { + long start = System.currentTimeMillis(); + System.out.println("读取文件" + fileName + "完成:" + readFileSync(fileName)); + if (null != fileName2) { + System.out.println("读取文件" + fileName2 + "完成:" + readFileSync(fileName2)); } - }).start(); + long stop = System.currentTimeMillis(); + System.out.println("程序结束了,总耗时:" + String.valueOf(stop - start) + " ms(毫秒)!\n"); + } catch (IOException e) { + e.printStackTrace(); + } } - static StringBuilder readFileSync(String fileName) throws IOException { + static JSONObject readFileSync(String fileName) throws IOException { File file = new File(fileName); InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file)); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); @@ -72,6 +101,6 @@ public class ThreadTest { sb.append(bufferedReader.readLine()); } sb.append("}"); - return sb; + return JSON.parseObject(sb.toString()); } } diff --git a/src/main/java/thread/juc/concurrent/TestCopyOnWriteArrayList.java b/src/main/java/thread/juc/concurrent/TestCopyOnWriteArrayList.java new file mode 100644 index 0000000..1012160 --- /dev/null +++ b/src/main/java/thread/juc/concurrent/TestCopyOnWriteArrayList.java @@ -0,0 +1,40 @@ +package thread.juc.concurrent; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class TestCopyOnWriteArrayList { + public static void main(String[] args) { + HelloThread helloThread = new HelloThread(); + for (int i = 0; i < 10; i++) { + new Thread(helloThread).start(); + } + } +} + +class HelloThread implements Runnable { + //ava.util.ConcurrentModificationException 并发修改异常 +// private static List list = Collections.synchronizedList(new ArrayList<>()); + /** + * 并发修改异常不见了,每次写入 复制新的链表 然后添加,但是效率低 适用并发迭代 + */ + private static CopyOnWriteArrayList list = new CopyOnWriteArrayList<>(); + + static { + list.add("AA"); + list.add("BB"); + list.add("CC"); + } + + @Override + public void run() { + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + System.out.println(iterator.next()); + list.add("DD"); + } + } +} diff --git a/src/main/java/thread/juc/countdownlatch/TestCountdownlatch.java b/src/main/java/thread/juc/countdownlatch/TestCountdownlatch.java new file mode 100644 index 0000000..dc9ece9 --- /dev/null +++ b/src/main/java/thread/juc/countdownlatch/TestCountdownlatch.java @@ -0,0 +1,53 @@ +package thread.juc.countdownlatch; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; + +/** + * 闭锁:在完成某些运算时,只有其他(线程)运算全部完成,当前运算才会继续执行 + * 计算多线程同时执行的时间 + */ +public class TestCountdownlatch { + public static void main(String[] args) { + final CountDownLatch countDownLatch = new CountDownLatch(5);//线程操作递减1 为0 任务完成 + LatchDemo latchDemo = new LatchDemo(countDownLatch); + long start = System.currentTimeMillis(); + for (int i = 0; i < 5; i++) { + new Thread(latchDemo).start(); + } + try { + countDownLatch.await();//注掉看效果 + long stop = System.currentTimeMillis(); + System.out.println("耗费时间为:" + (stop - start) + "/ms\r"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} + +class LatchDemo implements Runnable { + + private CountDownLatch latch; + + public LatchDemo() { + } + + public LatchDemo(CountDownLatch latch) { + this.latch = latch; + } + + @Override + public void run() { + try { + for (int i = 0; i < 5000; i++) { + if (i % 2 == 0) { + System.out.println(i); + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + latch.countDown();//闭锁减1 + } + } +} -- Gitee