From 9900e30e5d979968fa757531358dbf77a41f3c42 Mon Sep 17 00:00:00 2001 From: chen88358323 Date: Tue, 27 Sep 2022 10:09:26 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20=E5=A2=9E=E5=8A=A0lambda=20demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 46 ++-- .../cc/lambda/demo/ConvertTest.java | 219 ++++++++++++++++++ .../chap10/OperationsWithOptional.java | 30 +-- .../lambdasinaction/chap10/OptionalMain.java | 16 +- .../lambdasinaction/chap4/StreamBasic.java | 3 +- .../java/lambdasinaction/chap5/Answer.java | 159 +++++++++++++ .../chap6/CollectorHarness.java | 32 +-- .../java/lambdasinaction/chap6/Grouping.java | 172 +++++++------- .../chap6/PartitionPrimeNumbers.java | 168 +++++++------- .../lambdasinaction/chap7/cc/RunStream.java | 74 ++++++ .../lambdasinaction/chap7/cc/StreamDemo1.java | 37 +++ 11 files changed, 723 insertions(+), 233 deletions(-) create mode 100644 src/main/java/lambdasinaction/cc/lambda/demo/ConvertTest.java create mode 100644 src/main/java/lambdasinaction/chap5/Answer.java create mode 100644 src/main/java/lambdasinaction/chap7/cc/RunStream.java create mode 100644 src/main/java/lambdasinaction/chap7/cc/StreamDemo1.java diff --git a/pom.xml b/pom.xml index 10e5035e..c7e7b169 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ junit junit - 4.11 + 4.12 @@ -37,30 +37,30 @@ maven-compiler-plugin 3.1 - 1.9 - 1.9 + 1.8 + 1.8 - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - benchmarks - - - org.openjdk.jmh.Main - - - - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/lambdasinaction/cc/lambda/demo/ConvertTest.java b/src/main/java/lambdasinaction/cc/lambda/demo/ConvertTest.java new file mode 100644 index 00000000..b4789b59 --- /dev/null +++ b/src/main/java/lambdasinaction/cc/lambda/demo/ConvertTest.java @@ -0,0 +1,219 @@ +package lambdasinaction.cc.lambda.demo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @ClassName : ConvertTest + * @Description : + * @param: + * @Author : CC + * @Date: 2022-09-21 10:18 + */ +public class ConvertTest { + public static void main(String[] args) { + filterTest(); + groupTest(); + } + + private static void groupTest(){ + Map map=new HashMap<>(); + List list=new ArrayList<>(); + List userList=new ArrayList<>(); + User u=null; + for (int i = 0; i <100 ; i++) { + map.put("nname"+i,i/3); + list.add(i/3); + u=new User(i,"name"+i); + userList.add(u); + } +// Map gIntMap=userList.stream(). +// collect(Collectors.groupingBy(u.getName(),Collectors.counting(u.getAge()))); +// gIntMap.forEach((k,v)->{ +// System.out.println(k + " = " + v); +// }); +// System.out.println(gIntMap); + +// Map> list2=map.entrySet().stream().collect(Collectors.groupingBy( +// gmap->(gmap.getValue() ) +// ); + } + private static void filterTest(){ + Map map=new HashMap<>(); + List list=new ArrayList<>(); + List userList=new ArrayList<>(); + User u=null; + for (int i = 0; i <10 ; i++) { + map.put(i,"nname"+i); + list.add(i); + u=new User(i,"name"+i,i/3); + userList.add(u); + } +// Map< String,Integer> umap= + userList.stream().collect(Collectors.groupingBy(User::getName,Collectors.groupingBy(User::getAge))); + + + Stream> stream=map.entrySet().stream(); + + stream.filter(m->(m.getKey()>3)); + + + List ll=list.stream().filter(i->(i>3)).collect(Collectors.toList()); + for (Integer i:ll + ) { + System.out.print(i+" "); + } + System.out.println(); +// stream.filter(map->(id>3)); + + + userList.stream().filter(user -> (user.getId()>3)); + } + + + + private static void reduceTest(){ + Map map=new HashMap<>(); + List list=new ArrayList<>(); + List userList=new ArrayList<>(); + User u=null; + for (int i = 0; i <10 ; i++) { + map.put(i,"nname"+i); + list.add(i); + u=new User(i,"name"+i,i/3); + userList.add(u); + } + + int res=list.stream().reduce(0,(sum ,age)->sum+age); + System.out.println("reduce test List==>"+res); +// Map< String,Integer> umap= + + Integer num=userList.stream().map(k->(k.getAge())).reduce(new Integer(0),(sum ,age)->{ + sum+=age; + return sum; + }); + System.out.println("all user age sum=>"+num); + + Stream> stream=map.entrySet().stream(); + + stream.filter(m->(m.getKey()>3)); + + + List ll=list.stream().filter(i->(i>3)).collect(Collectors.toList()); + for (Integer i:ll + ) { + System.out.print(i+" "); + } + System.out.println(); +// stream.filter(map->(id>3)); + + + userList.stream().filter(user -> (user.getId()>3)); + } + + private static void mapTest(){ + Map map=new HashMap<>(); + List list=new ArrayList<>(); + List userList=new ArrayList<>(); + User u=null; + for (int i = 0; i <10 ; i++) { + map.put(i,"nname"+i); + list.add(i); + u=new User(i,"name"+i,i/3); + userList.add(u); + } +// List list case + List strlist=list.stream().map(num->num+"tset").collect(Collectors.toList()); + System.out.println(strlist); + + //map case +// map.entrySet().stream().map(entry->entry.getValue(),entry.ge) + + //userlist case + userList=userList.stream().map(user->{ + if(user.getAge()>15){ + user.setTag(1); + }else { + user.setTag(2); + } + return user; + }).collect(Collectors.toList()); + + + System.out.println(); + +// Stream> stream=map.entrySet().stream().map(entry->{ +// Map.Entry en; +// entry.getKey() +// ent +// +// }); + + + } +} +class User { + private Integer id; + private String name; + private Integer age; + private String country; + private int tag; + + public int getTag() { + return tag; + } + + public void setTag(int tag) { + this.tag = tag; + } + + public User(){} + public User(Integer id, String name) { + this.id = id; + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public User(Integer id, String name, Integer age) { + this.id = id; + this.name = name; + this.age = age; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java index d2940969..4c76c2d7 100644 --- a/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java +++ b/src/main/java/lambdasinaction/chap10/OperationsWithOptional.java @@ -7,19 +7,19 @@ public class OperationsWithOptional { - public static void main(String... args) { - System.out.println(max(of(3), of(5))); - System.out.println(max(empty(), of(5))); - - Optional opt1 = of(5); - Optional opt2 = opt1.or(() -> of(4)); - - System.out.println( - of(5).or(() -> of(4)) - ); - } - - public static final Optional max(Optional i, Optional j) { - return i.flatMap(a -> j.map(b -> Math.max(a, b))); - } +// public static void main(String... args) { +// System.out.println(max(of(3), of(5))); +// System.out.println(max(empty(), of(5))); +// +// Optional opt1 = of(5); +// Optional opt2 = opt1.or(() -> of(4)); +// +// System.out.println( +// of(5).or(() -> of(4)) +// ); +// } +// +// public static final Optional max(Optional i, Optional j) { +// return i.flatMap(a -> j.map(b -> Math.max(a, b))); +// } } diff --git a/src/main/java/lambdasinaction/chap10/OptionalMain.java b/src/main/java/lambdasinaction/chap10/OptionalMain.java index dcd97792..7910e1b8 100644 --- a/src/main/java/lambdasinaction/chap10/OptionalMain.java +++ b/src/main/java/lambdasinaction/chap10/OptionalMain.java @@ -13,12 +13,12 @@ public String getCarInsuranceName(Optional person) { .orElse("Unknown"); } - public Set getCarInsuranceNames(List persons) { - return persons.stream() - .map(Person::getCar) - .map(optCar -> optCar.flatMap(Car::getInsurance)) - .map(optInsurance -> optInsurance.map(Insurance::getName)) - .flatMap(Optional::stream) - .collect(toSet()); - } +// public Set getCarInsuranceNames(List persons) { +// return persons.stream() +// .map(Person::getCar) +// .map(optCar -> optCar.flatMap(Car::getInsurance)) +// .map(optInsurance -> optInsurance.map(Insurance::getName)) +// .flatMap(Optional::stream) +// .collect(toSet()); +// } } diff --git a/src/main/java/lambdasinaction/chap4/StreamBasic.java b/src/main/java/lambdasinaction/chap4/StreamBasic.java index 19a8c176..fd0c8f5e 100644 --- a/src/main/java/lambdasinaction/chap4/StreamBasic.java +++ b/src/main/java/lambdasinaction/chap4/StreamBasic.java @@ -30,6 +30,7 @@ public static List getLowCaloricDishesNamesInJava7(List dishes){ } List lowCaloricDishesName = new ArrayList<>(); Collections.sort(lowCaloricDishes, new Comparator() { + @Override public int compare(Dish d1, Dish d2){ return Integer.compare(d1.getCalories(), d2.getCalories()); } @@ -42,7 +43,7 @@ public int compare(Dish d1, Dish d2){ public static List getLowCaloricDishesNamesInJava8(List dishes){ return dishes.stream() - .filter(d -> d.getCalories() < 400) + .filter(d -> d.getCalories() >300) .sorted(comparing(Dish::getCalories)) .map(Dish::getName) .collect(toList()); diff --git a/src/main/java/lambdasinaction/chap5/Answer.java b/src/main/java/lambdasinaction/chap5/Answer.java new file mode 100644 index 00000000..37a02ca9 --- /dev/null +++ b/src/main/java/lambdasinaction/chap5/Answer.java @@ -0,0 +1,159 @@ +package lambdasinaction.chap5; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @ClassName : Answer + * Q: + * (1)找出2011年发生的所有交易,并按交易额排序(从低到高)。 + * (2) 交易员都在哪些不同的城市工作过? + * (3) 查找所有来自于剑桥的交易员,并按姓名排序。 + * (4) 返回所有交易员的姓名字符串,按字母顺序排序。 + * (5) 有没有交易员是在米兰工作的? + * (6) 打印生活在剑桥的交易员的所有交易额。 + * (7) 所有交易中,最高的交易额是多少? + * (8) 找到交易额最小的交易。 + * @Description : 第五章开头练习题 + * @param: + * @Author : CC + * @Date: 2022-09-22 09:39 + */ +public class Answer { + public static void main(String[] args) { + Trader raoul = new Trader("Raoul", "Cambridge"); + Trader mario = new Trader("Mario","Milan"); + Trader alan = new Trader("Alan","Cambridge"); + Trader brian = new Trader("Brian","Cambridge"); + List traderList=new ArrayList<>(); + traderList.add(raoul); + traderList.add(mario); + traderList.add(alan); + traderList.add(brian); + + + + List transactions = Arrays.asList( + new Transaction(brian, 2011, 300), + new Transaction(raoul, 2012, 1000), + new Transaction(raoul, 2011, 400), + new Transaction(mario, 2012, 710), + new Transaction(mario, 2012, 700), + new Transaction(alan, 2012, 950) + ); + + answer1(traderList,transactions); + + answer2(traderList,transactions); + + answer3(traderList,transactions); + + answer4(traderList,transactions); + + answer5(traderList,transactions); + } +/** + * @ClassName : Answer + * (1)找出2011年发生的所有交易,并按交易额排序(从低到高)。 + * (7) 所有交易中,最高的交易额是多少? + * (8) 找到交易额最小的交易。 + * */ + private static void answer1( List t1, List t2){ + System.out.println("start run method:"+getMethodName()); + List list; + list = t2.stream().filter(transaction -> transaction.getYear()==2011).sorted(Comparator.comparing(Transaction::getValue)).collect(Collectors.toList()); + System.out.println(list); + + } + private static String getMethodName(){ + StackTraceElement[] stackTrace = new Exception().getStackTrace(); + String methodName = stackTrace[1].getMethodName(); + return methodName; + } + + /** + * @ClassName : Answer + * (6) 打印生活在剑桥的交易员的所有交易额。 + */ + private static void answer6(List t1, List t2){ + System.out.println("start run method:"+getMethodName()); + +// List list =t1.stream().filter(trader -> ("Cambridge".equals(trader.getCity()))).collect(Collectors.toList()); +// .map((trader,)->(trader.getName().equals(tran.get))); +// +// t1.stream().findAny().ifPresent(trader -> { +// if (trader.getCity().equals("Milan")){ +// System.out.println(" Q4 trader:"+trader); +// } +// }); +// +// System.out.println("Q4.有没有交易员是在米兰工作的?"+res); + + } + /** + * @ClassName : Answer + * (5) 有没有交易员是在米兰工作的? + */ + private static void answer5(List t1, List t2){ + System.out.println("start run method:"+getMethodName()); + List list; + boolean res=t1.stream().anyMatch(trader -> (trader.getCity().equals("Milan"))); + t1.stream().findAny().ifPresent(trader -> { + if (trader.getCity().equals("Milan")){ + System.out.println(" Q4 trader:"+trader); + } + }); + + System.out.println("Q4.有没有交易员是在米兰工作的?"+res); + + } + /** + * @ClassName : Answer + * (4) 返回所有交易员的姓名字符串,按字母顺序排序。 + */ + private static void answer4(List t1, List t2){ + System.out.println("start run method:"+getMethodName()); + List list; + list = t1.stream(). + sorted(Comparator.comparing(Trader::getName)). + collect(Collectors.toList()); +//按字母顺序排序没有做 以下为正确答案 + String traderStr = + t1.stream() + .map(transaction -> transaction.getName()) + .distinct() + .sorted() + .reduce("", (n1, n2) -> n1 + n2);//TODO reduce 怎么用还不熟 + + System.out.println(list); + + } + /** + * @ClassName : Answer + * (3) 查找所有来自于剑桥的交易员,并按姓名排序。 + */ + private static void answer3 (List t1, List t2){ + System.out.println("start run method:"+getMethodName()); + List list; + list = t1.stream(). + filter(trader -> trader.getCity().equals("Cambridge")). + sorted(Comparator.comparing(Trader::getName)). + collect(Collectors.toList()); + + System.out.println(list); + + } +/** + * @ClassName : Answer + * (2) 交易员都在哪些不同的城市工作过? + */ + private static void answer2 (List t1, List t2){ + System.out.println("start run method:"+getMethodName()); + List list; + Map> map = t1.stream().collect(Collectors.groupingBy( Trader::getCity )); + + System.out.println(map.keySet()); + + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap6/CollectorHarness.java b/src/main/java/lambdasinaction/chap6/CollectorHarness.java index 8370be16..d351a5d7 100644 --- a/src/main/java/lambdasinaction/chap6/CollectorHarness.java +++ b/src/main/java/lambdasinaction/chap6/CollectorHarness.java @@ -4,20 +4,20 @@ public class CollectorHarness { - public static void main(String[] args) { - //System.out.println("Partitioning done in: " + execute(PartitionPrimeNumbers::partitionPrimes) + " msecs"); - System.out.println("Partitioning done in: " + execute(PartitionPrimeNumbers::partitionPrimesWithCustomCollector) + " msecs" ); - } - - private static long execute(Consumer primePartitioner) { - long fastest = Long.MAX_VALUE; - for (int i = 0; i < 10; i++) { - long start = System.nanoTime(); - primePartitioner.accept(1_000_000); - long duration = (System.nanoTime() - start) / 1_000_000; - if (duration < fastest) fastest = duration; - System.out.println("done in " + duration); - } - return fastest; - } +// public static void main(String[] args) { +// //System.out.println("Partitioning done in: " + execute(PartitionPrimeNumbers::partitionPrimes) + " msecs"); +// System.out.println("Partitioning done in: " + execute(PartitionPrimeNumbers::partitionPrimesWithCustomCollector) + " msecs" ); +// } +// +// private static long execute(Consumer primePartitioner) { +// long fastest = Long.MAX_VALUE; +// for (int i = 0; i < 10; i++) { +// long start = System.nanoTime(); +// primePartitioner.accept(1_000_000); +// long duration = (System.nanoTime() - start) / 1_000_000; +// if (duration < fastest) fastest = duration; +// System.out.println("done in " + duration); +// } +// return fastest; +// } } diff --git a/src/main/java/lambdasinaction/chap6/Grouping.java b/src/main/java/lambdasinaction/chap6/Grouping.java index 9105cc80..ee83a4c6 100644 --- a/src/main/java/lambdasinaction/chap6/Grouping.java +++ b/src/main/java/lambdasinaction/chap6/Grouping.java @@ -7,90 +7,90 @@ import static lambdasinaction.chap6.Dish.menu; public class Grouping { - - enum CaloricLevel { DIET, NORMAL, FAT }; - - public static void main(String ... args) { - System.out.println("Dishes grouped by type: " + groupDishesByType()); - System.out.println("Dish names grouped by type: " + groupDishNamesByType()); - System.out.println("Dish tags grouped by type: " + groupDishTagsByType()); - System.out.println("Caloric dishes grouped by type: " + groupCaloricDishesByType()); - System.out.println("Dishes grouped by caloric level: " + groupDishesByCaloricLevel()); - System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel()); - System.out.println("Count dishes in groups: " + countDishesInGroups()); - System.out.println("Most caloric dishes by type: " + mostCaloricDishesByType()); - System.out.println("Most caloric dishes by type: " + mostCaloricDishesByTypeWithoutOprionals()); - System.out.println("Sum calories by type: " + sumCaloriesByType()); - System.out.println("Caloric levels by type: " + caloricLevelsByType()); - } - - private static Map> groupDishesByType() { - return menu.stream().collect(groupingBy(Dish::getType)); - } - - private static Map> groupDishNamesByType() { - return menu.stream().collect(groupingBy(Dish::getType, mapping(Dish::getName, toList()))); - } - - private static Map> groupDishTagsByType() { - return menu.stream().collect(groupingBy(Dish::getType, flatMapping(dish -> dishTags.get( dish.getName() ).stream(), toSet()))); - } - - private static Map> groupCaloricDishesByType() { -// return menu.stream().filter(dish -> dish.getCalories() > 500).collect(groupingBy(Dish::getType)); - return menu.stream().collect(groupingBy(Dish::getType, filtering(dish -> dish.getCalories() > 500, toList()))); - } - - private static Map> groupDishesByCaloricLevel() { - return menu.stream().collect( - groupingBy(dish -> { - if (dish.getCalories() <= 400) return CaloricLevel.DIET; - else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; - else return CaloricLevel.FAT; - } )); - } - - private static Map>> groupDishedByTypeAndCaloricLevel() { - return menu.stream().collect( - groupingBy(Dish::getType, - groupingBy((Dish dish) -> { - if (dish.getCalories() <= 400) return CaloricLevel.DIET; - else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; - else return CaloricLevel.FAT; - } ) - ) - ); - } - - private static Map countDishesInGroups() { - return menu.stream().collect(groupingBy(Dish::getType, counting())); - } - - private static Map> mostCaloricDishesByType() { - return menu.stream().collect( - groupingBy(Dish::getType, - reducing((Dish d1, Dish d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2))); - } - - private static Map mostCaloricDishesByTypeWithoutOprionals() { - return menu.stream().collect( - groupingBy(Dish::getType, - collectingAndThen( - reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2), - Optional::get))); - } - - private static Map sumCaloriesByType() { - return menu.stream().collect(groupingBy(Dish::getType, - summingInt(Dish::getCalories))); - } - - private static Map> caloricLevelsByType() { - return menu.stream().collect( - groupingBy(Dish::getType, mapping( - dish -> { if (dish.getCalories() <= 400) return CaloricLevel.DIET; - else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; - else return CaloricLevel.FAT; }, - toSet() ))); - } +// +// enum CaloricLevel { DIET, NORMAL, FAT }; +// +// public static void main(String ... args) { +// System.out.println("Dishes grouped by type: " + groupDishesByType()); +// System.out.println("Dish names grouped by type: " + groupDishNamesByType()); +// System.out.println("Dish tags grouped by type: " + groupDishTagsByType()); +// System.out.println("Caloric dishes grouped by type: " + groupCaloricDishesByType()); +// System.out.println("Dishes grouped by caloric level: " + groupDishesByCaloricLevel()); +// System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel()); +// System.out.println("Count dishes in groups: " + countDishesInGroups()); +// System.out.println("Most caloric dishes by type: " + mostCaloricDishesByType()); +// System.out.println("Most caloric dishes by type: " + mostCaloricDishesByTypeWithoutOprionals()); +// System.out.println("Sum calories by type: " + sumCaloriesByType()); +// System.out.println("Caloric levels by type: " + caloricLevelsByType()); +// } +// +// private static Map> groupDishesByType() { +// return menu.stream().collect(groupingBy(Dish::getType)); +// } +// +// private static Map> groupDishNamesByType() { +// return menu.stream().collect(groupingBy(Dish::getType, mapping(Dish::getName, toList()))); +// } +// +// private static Map> groupDishTagsByType() { +// return menu.stream().collect(groupingBy(Dish::getType, flatMapping(dish -> dishTags.get( dish.getName() ).stream(), toSet()))); +// } +// +// private static Map> groupCaloricDishesByType() { +//// return menu.stream().filter(dish -> dish.getCalories() > 500).collect(groupingBy(Dish::getType)); +// return menu.stream().collect(groupingBy(Dish::getType, filtering(dish -> dish.getCalories() > 500, toList()))); +// } +// +// private static Map> groupDishesByCaloricLevel() { +// return menu.stream().collect( +// groupingBy(dish -> { +// if (dish.getCalories() <= 400) return CaloricLevel.DIET; +// else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; +// else return CaloricLevel.FAT; +// } )); +// } +// +// private static Map>> groupDishedByTypeAndCaloricLevel() { +// return menu.stream().collect( +// groupingBy(Dish::getType, +// groupingBy((Dish dish) -> { +// if (dish.getCalories() <= 400) return CaloricLevel.DIET; +// else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; +// else return CaloricLevel.FAT; +// } ) +// ) +// ); +// } +// +// private static Map countDishesInGroups() { +// return menu.stream().collect(groupingBy(Dish::getType, counting())); +// } +// +// private static Map> mostCaloricDishesByType() { +// return menu.stream().collect( +// groupingBy(Dish::getType, +// reducing((Dish d1, Dish d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2))); +// } +// +// private static Map mostCaloricDishesByTypeWithoutOprionals() { +// return menu.stream().collect( +// groupingBy(Dish::getType, +// collectingAndThen( +// reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2), +// Optional::get))); +// } +// +// private static Map sumCaloriesByType() { +// return menu.stream().collect(groupingBy(Dish::getType, +// summingInt(Dish::getCalories))); +// } +// +// private static Map> caloricLevelsByType() { +// return menu.stream().collect( +// groupingBy(Dish::getType, mapping( +// dish -> { if (dish.getCalories() <= 400) return CaloricLevel.DIET; +// else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; +// else return CaloricLevel.FAT; }, +// toSet() ))); +// } } diff --git a/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java index 69d7c4ca..98dcddcd 100644 --- a/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java +++ b/src/main/java/lambdasinaction/chap6/PartitionPrimeNumbers.java @@ -8,33 +8,33 @@ import static java.util.stream.Collector.Characteristics.*; public class PartitionPrimeNumbers { - - public static void main(String ... args) { - System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimes(100)); - System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimesWithCustomCollector(100)); - - } - - public static Map> partitionPrimes(int n) { - return IntStream.rangeClosed(2, n).boxed() - .collect(partitioningBy(candidate -> isPrime(candidate))); - } - - public static boolean isPrime(int candidate) { - return IntStream.rangeClosed(2, candidate-1) - .limit((long) Math.floor(Math.sqrt((double) candidate)) - 1) - .noneMatch(i -> candidate % i == 0); - } - - public static Map> partitionPrimesWithCustomCollector(int n) { - return IntStream.rangeClosed(2, n).boxed().collect(new PrimeNumbersCollector()); - } - - public static boolean isPrime(List primes, Integer candidate) { - double candidateRoot = Math.sqrt((double) candidate); - //return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0); - return primes.stream().takeWhile(i -> i <= candidateRoot).noneMatch(i -> candidate % i == 0); - } +// +// public static void main(String ... args) { +// System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimes(100)); +// System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimesWithCustomCollector(100)); +// +// } +// +// public static Map> partitionPrimes(int n) { +// return IntStream.rangeClosed(2, n).boxed() +// .collect(partitioningBy(candidate -> isPrime(candidate))); +// } +// +// public static boolean isPrime(int candidate) { +// return IntStream.rangeClosed(2, candidate-1) +// .limit((long) Math.floor(Math.sqrt((double) candidate)) - 1) +// .noneMatch(i -> candidate % i == 0); +// } +// +// public static Map> partitionPrimesWithCustomCollector(int n) { +// return IntStream.rangeClosed(2, n).boxed().collect(new PrimeNumbersCollector()); +// } +// +// public static boolean isPrime(List primes, Integer candidate) { +// double candidateRoot = Math.sqrt((double) candidate); +// //return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0); +// return primes.stream().takeWhile(i -> i <= candidateRoot).noneMatch(i -> candidate % i == 0); +// } /* public static List takeWhile(List list, Predicate p) { int i = 0; @@ -46,61 +46,61 @@ public static List takeWhile(List list, Predicate p) { } return list; } -*/ - public static class PrimeNumbersCollector - implements Collector>, Map>> { - - @Override - public Supplier>> supplier() { - return () -> new HashMap>() {{ - put(true, new ArrayList()); - put(false, new ArrayList()); - }}; - } - - @Override - public BiConsumer>, Integer> accumulator() { - return (Map> acc, Integer candidate) -> { - acc.get( isPrime( acc.get(true), - candidate) ) - .add(candidate); - }; - } - - @Override - public BinaryOperator>> combiner() { - return (Map> map1, Map> map2) -> { - map1.get(true).addAll(map2.get(true)); - map1.get(false).addAll(map2.get(false)); - return map1; - }; - } - - @Override - public Function>, Map>> finisher() { - return i -> i; - } - - @Override - public Set characteristics() { - return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH)); - } - } - - public Map> partitionPrimesWithInlineCollector(int n) { - return Stream.iterate(2, i -> i + 1).limit(n) - .collect( - () -> new HashMap>() {{ - put(true, new ArrayList()); - put(false, new ArrayList()); - }}, - (acc, candidate) -> { - acc.get( isPrime(acc.get(true), candidate) ) - .add(candidate); - }, - (map1, map2) -> { - map1.get(true).addAll(map2.get(true)); - map1.get(false).addAll(map2.get(false)); - }); - } +//*/ +// public static class PrimeNumbersCollector +// implements Collector>, Map>> { +// +// @Override +// public Supplier>> supplier() { +// return () -> new HashMap>() {{ +// put(true, new ArrayList()); +// put(false, new ArrayList()); +// }}; +// } +// +// @Override +// public BiConsumer>, Integer> accumulator() { +// return (Map> acc, Integer candidate) -> { +// acc.get( isPrime( acc.get(true), +// candidate) ) +// .add(candidate); +// }; +// } +// +// @Override +// public BinaryOperator>> combiner() { +// return (Map> map1, Map> map2) -> { +// map1.get(true).addAll(map2.get(true)); +// map1.get(false).addAll(map2.get(false)); +// return map1; +// }; +// } +// +// @Override +// public Function>, Map>> finisher() { +// return i -> i; +// } +// +// @Override +// public Set characteristics() { +// return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH)); +// } +// } +// +// public Map> partitionPrimesWithInlineCollector(int n) { +// return Stream.iterate(2, i -> i + 1).limit(n) +// .collect( +// () -> new HashMap>() {{ +// put(true, new ArrayList()); +// put(false, new ArrayList()); +// }}, +// (acc, candidate) -> { +// acc.get( isPrime(acc.get(true), candidate) ) +// .add(candidate); +// }, +// (map1, map2) -> { +// map1.get(true).addAll(map2.get(true)); +// map1.get(false).addAll(map2.get(false)); +// }); +// } } diff --git a/src/main/java/lambdasinaction/chap7/cc/RunStream.java b/src/main/java/lambdasinaction/chap7/cc/RunStream.java new file mode 100644 index 00000000..60be2245 --- /dev/null +++ b/src/main/java/lambdasinaction/chap7/cc/RunStream.java @@ -0,0 +1,74 @@ +package lambdasinaction.chap7.cc; + +/** + * @ClassName : RunStream + * @Description : + * @param: + * @Author : CC + * @Date: 2022-08-19 18:47 + */ + +import java.util.Random; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +/** + * 验证stream运行机制 + * + * 1. 所有操作是链式调用, 一个元素只迭代一次 + * 2. 每一个中间操作返回一个新的流. 流里面有一个属性sourceStage + * 指向同一个 地方,就是Head + * 3. Head->nextStage->nextStage->... -> null + * 4. 有状态操作会把无状态操作阶段,单独处理 + * 5. 并行环境下, 有状态的中间操作不一定能并行操作. + * + * 6. parallel/ sequetial 这2个操作也是中间操作(也是返回stream) + * 但是他们不创建流, 他们只修改 Head的并行标志 + * + * @author 晓风轻 + * + */ +public class RunStream { + + public static void main(String[] args) { + Random random = new Random(); + // 随机产生数据 + Stream stream = Stream.generate(() -> random.nextInt(100)) + // 产生500个 ( 无限流需要短路操作. ) + .limit(500) + // 第1个无状态操作 + .peek(s -> print("peek: " + s)) + // 第2个无状态操作 + .filter(s -> { + print("filter: " + s); + return s > 90; + }) + // 有状态操作 + .sorted((i1, i2) -> { + print("排序: " + i1 + ", " + i2); + return i1.compareTo(i2); + }) + // 又一个无状态操作 + .peek(s -> { + print("peek2: " + s); + }).parallel(); + + // 终止操作 + stream.count(); + } + + /** + * 打印日志并sleep 5 毫秒 + * + * @param s + */ + public static void print(String s) { + // System.out.println(s); + // 带线程名(测试并行情况) + System.out.println(Thread.currentThread().getName() + " > " + s); + try { + TimeUnit.MILLISECONDS.sleep(5); + } catch (InterruptedException e) { + } + } +} \ No newline at end of file diff --git a/src/main/java/lambdasinaction/chap7/cc/StreamDemo1.java b/src/main/java/lambdasinaction/chap7/cc/StreamDemo1.java new file mode 100644 index 00000000..ca13393a --- /dev/null +++ b/src/main/java/lambdasinaction/chap7/cc/StreamDemo1.java @@ -0,0 +1,37 @@ +package lambdasinaction.chap7.cc; + +/** + * @ClassName : StreamDemo1 + * @Description : + * @param: + * @Author : CC + * @Date: 2022-08-19 18:42 + */ +import java.util.stream.IntStream; + +public class StreamDemo1 { + + public static void main(String[] args) { + int[] nums = { 1, 2, 3 }; + // 外部迭代 + int sum = 0; + for (int i : nums) { + sum += i; + } + System.out.println("1结果为:" + sum); + + // 使用stream的内部迭代 + // map就是中间操作(返回stream的操作) + // sum就是终止操作 + int sum2 = IntStream.of(nums).map(StreamDemo1::doubleNum).sum(); + System.out.println("2结果为:" + sum2); + + System.out.println("惰性求值就是终止没有调用的情况下,中间操作不会执行"); + IntStream.of(nums).map(StreamDemo1::doubleNum); + } + + public static int doubleNum(int i) { + System.out.println("执行了乘以2"); + return i * 2; + } +} \ No newline at end of file From 6240dfa2551fc66f500801d372cab97380be8b62 Mon Sep 17 00:00:00 2001 From: chen88358323 Date: Sun, 23 Apr 2023 16:20:47 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0gson=E4=BE=9D=E8=B5=96=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0leetcode=20=E7=AE=97=E6=B3=95=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 12 ++ .../org/cc/leetcode/onehundred/Num11.java | 86 ++++++++++ .../org/cc/leetcode/onehundred/Num14.java | 93 +++++++++++ .../org/cc/leetcode/onehundred/Num15.java | 119 ++++++++++++++ .../org/cc/leetcode/onehundred/Num18.java | 40 +++++ .../org/cc/leetcode/onehundred/ten/Num01.java | 91 +++++++++++ .../org/cc/leetcode/onehundred/ten/Num02.java | 97 +++++++++++ .../org/cc/leetcode/onehundred/ten/Num03.java | 64 ++++++++ .../org/cc/leetcode/onehundred/ten/Num04.java | 86 ++++++++++ .../org/cc/leetcode/onehundred/ten/Num05.java | 55 +++++++ .../org/cc/leetcode/onehundred/ten/Num06.java | 97 +++++++++++ .../org/cc/leetcode/onehundred/ten/Num08.java | 152 ++++++++++++++++++ .../org/cc/leetcode/onehundred/ten/Num09.java | 70 ++++++++ .../java/org/cc/leetcode/util/ListNode.java | 136 ++++++++++++++++ .../java/org/cc/thread/AtomicIntegerDemo.java | 82 ++++++++++ 15 files changed, 1280 insertions(+) create mode 100644 src/main/java/org/cc/leetcode/onehundred/Num11.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/Num14.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/Num15.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/Num18.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num01.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num02.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num03.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num04.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num05.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num06.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num08.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/ten/Num09.java create mode 100644 src/main/java/org/cc/leetcode/util/ListNode.java create mode 100644 src/main/java/org/cc/thread/AtomicIntegerDemo.java diff --git a/pom.xml b/pom.xml index c7e7b169..e997508b 100644 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,18 @@ junit 4.12 + + + + com.google.code.gson + gson + 2.8.5 + + + com.google.code.gson + gson + 2.9.0 + diff --git a/src/main/java/org/cc/leetcode/onehundred/Num11.java b/src/main/java/org/cc/leetcode/onehundred/Num11.java new file mode 100644 index 00000000..80c64c62 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/Num11.java @@ -0,0 +1,86 @@ +package org.cc.leetcode.onehundred; + +/** + * https://leetcode.cn/problems/container-with-most-water/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num11 { + public static void main(String[] args) { + Num11 test=new Num11(); +// ListNode.printListNode(); + int[] tar={1,8,6,2,5,4,8,3,7}; + int res=test.maxArea2(tar); + System.out.println("res "+res); + } + public int maxArea(int[] arr) { + if(arr==null||arr.length<2){ + return 0; + }else { + int sta=0; + int end=arr.length-1; + int sum=0; + while (stastr2.length()?str2.length(): str1.length(); + char[] str1Array=str1.toCharArray(); + char[] str2Array=str2.toCharArray(); + for (int i = 0; i < l; i++) { + if(str1Array[i]==str2Array[i]){ + sb.append(str1Array[i]); + }else { + break; + } + } + return sb.toString(); + } + } +} + + + +/**** + *编写一个函数来查找字符串数组中的最长公共前缀。 + * + * 如果不存在公共前缀,返回空字符串 ""。 + * + * + * + * 示例 1: + * + * 输入:strs = ["flower","flow","flight"] + * 输出:"fl" + * 示例 2: + * + * 输入:strs = ["dog","racecar","car"] + * 输出:"" + * 解释:输入不存在公共前缀。 + * + * + * 提示: + * + * 1 <= strs.length <= 200 + * 0 <= strs[i].length <= 200 + * strs[i] 仅由小写英文字母组成 + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/Num15.java b/src/main/java/org/cc/leetcode/onehundred/Num15.java new file mode 100644 index 00000000..d1800c34 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/Num15.java @@ -0,0 +1,119 @@ +package org.cc.leetcode.onehundred; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * https://leetcode.cn/problems/container-with-most-water/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num15 { + public static void main(String[] args) { + Num15 test=new Num15(); +// ListNode.printListNode(); + int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; + + + List> res=test.threeSum(tar); + Gson gson = new GsonBuilder().serializeNulls().create(); + String text = gson.toJson(res); + System.out.println("res "+text); + } + + private void dellistNode(List list,int num){ + list.remove(0); +// list.lastIndexOf() + } + public List> threeSum(int[] nums) { + Set> resset=new HashSet>(); + List numslist=Arrays.stream(nums).boxed().collect(Collectors.toList()); + Arrays.stream(nums).boxed().collect(Collectors.toList()); + int len=nums.length-1; + if(nums==null||nums.length<2){ + return null; + }else { + for (int i = 0; i list=new ArrayList<>(); + list.add(fir); + list.add(sen);list.add(thi); + Collections.sort(list); + resset.add(list); + } + } + } + List> reslist=new ArrayList>(resset); + return reslist; + } + //双指针查找数字 + private String findNum(Integer[] tar,int num){ + System.out.println("tar is "+tar); + String res=null; + //判断在外面做 + if(tar==null||tar.length==0){ + + }else if(tar.length==1){ + if(tar[0]==num){ + return num+""; + } + }else { + int sta =0; + int end=tar.length-1; + while (sta set = new HashSet<>(); + while(r0){//奇数为 + System.out.println("res:"+tar[num]); + return Double.valueOf(tar[num]+""); + }else{ + System.out.println("res:"+tar[num]+" and "+tar[num-1]); + double d=(double)(tar[num]+tar[num-1])/2; + return d; + } + } + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + double resd=0.0; + if((nums1==null||nums1.length==0)&&(nums2==null||nums2.length==0)){ + return resd; + }else {//两个都为空的先不处理,处理两个都不为空 + int len1 = nums1.length - 1; + int len2 = nums2.length - 1; + int reslen = len1 + len2 + 1; + int[] res = new int[reslen+1]; + //1.合并成一个数组 + while(reslen>-1){ + if(len1==-1){ + res[reslen]=nums2[len2]; + len2--; + reslen--; + }else if(len2==-1){ + res[reslen]=nums1[len1]; + reslen--; + len1--; + }else{ + if (nums1[len1] >= nums2[len2]) { + res[reslen] = nums1[len1]; + len1--; + } else { + res[reslen] = nums2[len2]; + len2--; + } + reslen--; + } + } //结果处理 + return getMiddleNum(res); + } + + } +} diff --git a/src/main/java/org/cc/leetcode/onehundred/ten/Num05.java b/src/main/java/org/cc/leetcode/onehundred/ten/Num05.java new file mode 100644 index 00000000..530f0a1a --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/ten/Num05.java @@ -0,0 +1,55 @@ +package org.cc.leetcode.onehundred.ten; + +/** + * todo + * https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/?languageTags=java + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + *给你一个字符串 s,找到 s 中最长的回文子串。 + * + * 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 + * + * + * + * 示例 1: + * + * 输入:s = "babad" + * 输出:"bab" + * 解释:"aba" 同样是符合题意的答案。 + * 示例 2: + * + * 输入:s = "cbbd" + * 输出:"bb" + * + * + * 提示: + * + * 1 <= s.length <= 1000 + * s 仅由数字和英文字母组成 + */ +public class Num05 { + public static void main(String[] args) { + Num05 test=new Num05(); + int[] t1={1,2}; + int[] t2={3,4}; + test.longestPalindrome("ssssssddsadafa"); +// ListNode.printListNode(); + + } + public String longestPalindrome(String s) { + if(s==null||s.length()==0){ + return null; + } + StringBuffer sb=new StringBuffer(s); + String s2=sb.reverse().toString(); + for (int i = 0; i sblist=new ArrayList<>(numRows); + for (int i = 0; i < numRows; i++) { + sblist.add(new StringBuilder()); + } + int i=0,flag=-1; + for (char b:s.toCharArray() + ) { + sblist.get(i).append(b); + if(i==0||i==numRows-1){ + flag=-flag; + } + i+=flag; + } + StringBuilder builder=new StringBuilder(); + for (int j = 0; j rows = new ArrayList(); +// for(int i = 0; i < numRows; i++) +// rows.add(new StringBuilder()); +// int i = 0, flag = -1; +// for(char c : s.toCharArray()) { +// rows.get(i).append(c); +// if(i == 0 || i == numRows -1) +// flag = - flag; +// i += flag; +// } +// StringBuilder res = new StringBuilder(); +// for(StringBuilder row : rows) res.append(row); +// return res.toString(); \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/ten/Num08.java b/src/main/java/org/cc/leetcode/onehundred/ten/Num08.java new file mode 100644 index 00000000..b7a25eb9 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/ten/Num08.java @@ -0,0 +1,152 @@ +package org.cc.leetcode.onehundred.ten; + +import java.util.ArrayList; +import java.util.List; + +/** + * todo + * https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/?languageTags=java + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num08 { + public static void main(String[] args) { + Num08 test=new Num08(); +// ListNode.printListNode(); +// int res=test.myAtoi("4193 with words"); +// int res=test.myAtoi("words and 987"); +// int res=test.myAtoi( "3.14159"); +// int res=test.myAtoi("-91283472332"); + int res=test.myAtoi(" -42"); + System.out.println("res "+res); + } + private List initList(){ + String str="0123456789.-"; + ArrayList list=new ArrayList<>(); + for (char c:str.toCharArray() + ) { + list.add(c); + } + return list; + } + + public int myAtoi(String s) { + + s=s.trim();//去掉空格 + boolean bignum=true;//正负数 true 正数 + + List list=initList(); + StringBuilder sb=new StringBuilder(); + for (char c: + s.toCharArray()) { + if(list.contains(c)){ + sb.append(c); + } + } + String temp=sb.toString(); + if(temp.contains("-")){//判断正负 + bignum=false; + } + + System.out.println("temp: "+temp); + Integer num=0; + try { + + num=Integer.valueOf(temp); + + if(s.indexOf(num+"")>1){//起始为字母 + num=0; + } + + }catch (Exception e){ + System.out.println("error: "+e.getMessage()); + + if(temp.contains(".")){//小数处理 + Double dnum=new Double(temp); + num= dnum.intValue(); + System.out.println("double"+dnum.intValue()); + } + Long lnum=new Long(temp); + if(lnum>Integer.MAX_VALUE){ + num = 0; + }else if(lnum 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。 + * 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。 + * 返回整数作为最终结果。 + * 注意: + * + * 本题中的空白字符只包括空格字符 ' ' 。 + * 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。 + * + * + * 示例 1: + * + * 输入:s = "42" + * 输出:42 + * 解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。 + * 第 1 步:"42"(当前没有读入字符,因为没有前导空格) + * ^ + * 第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+') + * ^ + * 第 3 步:"42"(读入 "42") + * ^ + * 解析得到整数 42 。 + * 由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。 + * 示例 2: + * + * 输入:s = " -42" + * 输出:-42 + * 解释: + * 第 1 步:" -42"(读入前导空格,但忽视掉) + * ^ + * 第 2 步:" -42"(读入 '-' 字符,所以结果应该是负数) + * ^ + * 第 3 步:" -42"(读入 "42") + * ^ + * 解析得到整数 -42 。 + * 由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。 + * 示例 3: + * + * 输入:s = "4193 with words" + * 输出:4193 + * 解释: + * 第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格) + * ^ + * 第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+') + * ^ + * 第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止) + * ^ + * 解析得到整数 4193 。 + * 由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193 。 + * + * + * 提示: + * + * 0 <= s.length <= 200 + * s 由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成 + * + * **/ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/ten/Num09.java b/src/main/java/org/cc/leetcode/onehundred/ten/Num09.java new file mode 100644 index 00000000..3ce2c25f --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/ten/Num09.java @@ -0,0 +1,70 @@ +package org.cc.leetcode.onehundred.ten; + +/** + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num09 { + public static void main(String[] args) { + Num09 test=new Num09(); +// ListNode.printListNode(); +// int res=test.myAtoi("4193 with words"); +// int res=test.myAtoi("words and 987"); +// int res=test.myAtoi( "3.14159"); +// int res=test.myAtoi("-91283472332"); + boolean res=test.isPalindrome(1221); + System.out.println("res "+res); + } + public boolean isPalindrome(int x) { + boolean res=true; + if(x<0){ + return false; + }else if(x<10){ + return true; + }else { + String ste=x+""; + char[] charArr=ste.toCharArray(); + for (int i = 0,j=charArr.length-1; i 0){ + for (int i = 0; i { + for (int j = 0; j < 1000; j++) { + sum1++; + } + latch.countDown(); + }); + } + Arrays.stream(ts).forEach((t)->t.start()); + latch.await(); + System.out.println("test:"+sum1); + } + + // 县城不安全的 + private static void test2() throws InterruptedException{ + sum1=0; + Object o=new Object(); + Thread[] ts=new Thread[90]; + CountDownLatch latch=new CountDownLatch(ts.length); + for (int i = 0; i < ts.length; i++) { + + ts[i]=new Thread(()->{ + synchronized (o){ + + for (int j = 0; j < 1000; j++) { + sum1++; + } + latch.countDown(); + } + }); + } + Arrays.stream(ts).forEach((t)->t.start()); + latch.await(); + System.out.println("test2:"+sum1); + } + + + private static void test3()throws InterruptedException{ + Thread[] ts=new Thread[90]; + CountDownLatch latch=new CountDownLatch(ts.length); + for (int i = 0; i < ts.length; i++) { + + ts[i]=new Thread(()->{ + for (int j = 0; j < 1000; j++) { + sum3.incrementAndGet(); + } + latch.countDown(); + }); + } + Arrays.stream(ts).forEach((t)->t.start()); + latch.await(); + System.out.println("test3:"+sum3); + } +} \ No newline at end of file From 688e80b09e6225b3e5cd312fea1a47ac095158b2 Mon Sep 17 00:00:00 2001 From: chen88358323 Date: Mon, 24 Apr 2023 10:06:12 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A9=AC=E5=A3=AB?= =?UTF-8?q?=E5=85=B5=20=E7=BA=BF=E7=A8=8B=E8=AF=BE=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/cc/leetcode/onehundred/Num15.java | 128 ++++++++++++++---- src/main/java/org/cc/thread/CasAbaDemo.java | 70 ++++++++++ .../reentantlock/T01_ReentrantLock1.java | 39 ++++++ .../reentantlock/T02_ReentrantLock2.java | 55 ++++++++ .../reentantlock/T03_ReentrantLock3.java | 72 ++++++++++ .../reentantlock/T04_ReentrantLock4.java | 68 ++++++++++ .../reentantlock/T05_ReentrantLock5.java | 43 ++++++ .../reentantlock/T06_TestCountDownLatch.java | 60 ++++++++ .../reentantlock/T07_TestCyclicBarrier.java | 36 +++++ .../thread/reentantlock/T08_TestPhaser.java | 88 ++++++++++++ .../thread/reentantlock/T09_TestPhaser2.java | 120 ++++++++++++++++ .../reentantlock/T10_TestReadWriteLock.java | 61 +++++++++ .../reentantlock/T11_TestSemaphore.java | 41 ++++++ .../reentantlock/T12_TestExchanger.java | 47 +++++++ .../reentantlock/T13_TestLockSupport.java | 36 +++++ 15 files changed, 936 insertions(+), 28 deletions(-) create mode 100644 src/main/java/org/cc/thread/CasAbaDemo.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T01_ReentrantLock1.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T02_ReentrantLock2.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T03_ReentrantLock3.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T04_ReentrantLock4.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T05_ReentrantLock5.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T06_TestCountDownLatch.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T07_TestCyclicBarrier.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T08_TestPhaser.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T09_TestPhaser2.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T10_TestReadWriteLock.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T11_TestSemaphore.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T12_TestExchanger.java create mode 100644 src/main/java/org/cc/thread/reentantlock/T13_TestLockSupport.java diff --git a/src/main/java/org/cc/leetcode/onehundred/Num15.java b/src/main/java/org/cc/leetcode/onehundred/Num15.java index d1800c34..3e389b20 100644 --- a/src/main/java/org/cc/leetcode/onehundred/Num15.java +++ b/src/main/java/org/cc/leetcode/onehundred/Num15.java @@ -29,15 +29,26 @@ public static void main(String[] args) { System.out.println("res "+text); } - private void dellistNode(List list,int num){ - list.remove(0); -// list.lastIndexOf() + private void removeListNode(int i,List tarlist){ + if(tarlist==null||tarlist.size()==0){ + return; + }else { + if(tarlist.indexOf(i)==0){ + tarlist.remove(0); + } + } } public List> threeSum(int[] nums) { Set> resset=new HashSet>(); - List numslist=Arrays.stream(nums).boxed().collect(Collectors.toList()); + + //search res list + List tarlist=Arrays.stream(nums).boxed().collect(Collectors.toList()); + +// List numslist=Arrays.stream(nums).boxed().collect(Collectors.toList()); + Arrays.stream(nums).boxed().collect(Collectors.toList()); - int len=nums.length-1; +// int len=nums.length-1; +// int[] temparra= Arrays.stream(nums).toArray(); if(nums==null||nums.length<2){ return null; }else { @@ -45,20 +56,21 @@ public List> threeSum(int[] nums) { int fir=nums[i]; int sen=nums[i+1]; int thi=0-fir-sen; - dellistNode(numslist,fir); - dellistNode(numslist,sen); - numslist.subList(i+1,len); - String res=findNum(numslist.stream().toArray(Integer[]::new),thi); + removeListNode(fir,tarlist); + removeListNode(sen,tarlist); + String res=findNum(tarlist,thi); if(res!=null&&!"".equals(res)){//建议使用StringUtils.isBlank() System.out.println("thi:"+res); thi=Integer.valueOf(res); - dellistNode(numslist,thi); - int[] resArr=new int[]{fir,sen ,thi}; +// dellistNode(numslist,thi); ArrayList list=new ArrayList<>(); - list.add(fir); - list.add(sen);list.add(thi); - Collections.sort(list); - resset.add(list); +// if((fir!=sen&&sen!=thi&&thi!=fir)||(fir==sen&&sen==thi&&thi==fir&&fir==0)){ + list.add(fir); + list.add(sen);list.add(thi); + Collections.sort(list); + resset.add(list); +// } + } } } @@ -66,25 +78,20 @@ public List> threeSum(int[] nums) { return reslist; } //双指针查找数字 - private String findNum(Integer[] tar,int num){ - System.out.println("tar is "+tar); + private String findNum(List list,int num){ String res=null; //判断在外面做 - if(tar==null||tar.length==0){ + if(list==null||list.size()==0){ - }else if(tar.length==1){ - if(tar[0]==num){ + }else if(list.size()==1){ + if(list.get(0)==num){ return num+""; } }else { - int sta =0; - int end=tar.length-1; - while (sta-1){ + res=num+""; + return res; + } } return res; @@ -116,4 +123,69 @@ private String findNum(Integer[] tar,int num){ * 1 <= strs.length <= 200 * 0 <= strs[i].length <= 200 * strs[i] 仅由小写英文字母组成 + * */ + + + +/**** + * + * private void dellistNode(List list,int num){ + * list.remove(0); + * // list.lastIndexOf() + * } + * public List> threeSum(int[] nums) { + * Set> resset=new HashSet>(); + * List numslist=Arrays.stream(nums).boxed().collect(Collectors.toList()); + * Arrays.stream(nums).boxed().collect(Collectors.toList()); + * // int len=nums.length-1; + * // int[] temparra= Arrays.stream(nums).toArray(); + * if(nums==null||nums.length<2){ + * return null; + * }else { + * for (int i = 0; i list=new ArrayList<>(); + * list.add(fir); + * list.add(sen);list.add(thi); + * Collections.sort(list); + * resset.add(list); + * } + * } + * } + * List> reslist=new ArrayList>(resset); + * return reslist; + * } + * //双指针查找数字 + * private String findNum(Integer[] tar,int num){ + * System.out.println("tar is "+tar); + * String res=null; + * //判断在外面做 + * if(tar==null||tar.length==0){ + * + * }else if(tar.length==1){ + * if(tar[0]==num){ + * return num+""; + * } + * }else { + * int sta =0; + * int end=tar.length-1; + * while (sta stamp = new AtomicStampedReference<>(100, 1); + public static void main(String[] args) throws InterruptedException{ + CasAbaDemo cad=new CasAbaDemo(); +// cad.test1(); + cad.testABAVersion(); + } + private void testABAVersion(){ + new Thread(() -> { + System.out.println(Thread.currentThread().getName() + " 第1次版本号:" + stamp.getStamp()+" val"+stamp.getReference()); + stamp.compareAndSet(100, 200, stamp.getStamp(), stamp.getStamp() + 1); + System.out.println(Thread.currentThread().getName() + " 第2次版本号:" + stamp.getStamp()+" val"+stamp.getReference()); + stamp.compareAndSet(200, 100, stamp.getStamp(), stamp.getStamp() + 1);//为什么这句话,值没有变? + System.out.println(Thread.currentThread().getName() + " 第2次版本号:" + stamp.getStamp()+" val"+stamp.getReference()); + }).start(); + + new Thread(() -> { + try { + TimeUnit.SECONDS.sleep(3); + System.out.println(Thread.currentThread().getName() + " 第1次版本号:" + stamp.getStamp()+" val"+stamp.getReference()); + stamp.compareAndSet(100, 400, stamp.getStamp(), stamp.getStamp() + 1); + System.out.println(Thread.currentThread().getName() + " 获取到的值:" + stamp.getReference()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); + } + //it's aba + private void test1() throws InterruptedException { + new Thread(() -> { + num.compareAndSet(100, 101); + System.out.println(Thread.currentThread().getName() + " 修改num之后的值:" + num.get()); + }).start(); + new Thread(() -> { + try { + TimeUnit.SECONDS.sleep(2); + num.compareAndSet(101, 100); + System.out.println(Thread.currentThread().getName() + " 修改num之后的值:" + num.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); + new Thread(() -> { + try { + TimeUnit.SECONDS.sleep(4); + num.compareAndSet(100, 200); + System.out.println(Thread.currentThread().getName() + " 修改num之后的值:" + num.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); + } + } diff --git a/src/main/java/org/cc/thread/reentantlock/T01_ReentrantLock1.java b/src/main/java/org/cc/thread/reentantlock/T01_ReentrantLock1.java new file mode 100644 index 00000000..282e4286 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T01_ReentrantLock1.java @@ -0,0 +1,39 @@ +/** + * reentrantlock�������synchronized + * ����������m1����this,ֻ��m1ִ����ϵ�ʱ��,m2����ִ�� + * �����Ǹ�ϰsynchronized��ԭʼ������ + * @author mashibing + */ +package org.cc.thread.reentantlock; + +import java.util.concurrent.TimeUnit; + +public class T01_ReentrantLock1 { + synchronized void m1() { + for(int i=0; i<10; i++) { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(i); + if(i == 2) m2(); + } + + } + + synchronized void m2() { + System.out.println("m2 ..."); + } + + public static void main(String[] args) { + T01_ReentrantLock1 rl = new T01_ReentrantLock1(); + new Thread(rl::m1).start(); + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //new Thread(rl::m2).start(); + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T02_ReentrantLock2.java b/src/main/java/org/cc/thread/reentantlock/T02_ReentrantLock2.java new file mode 100644 index 00000000..3c8cebde --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T02_ReentrantLock2.java @@ -0,0 +1,55 @@ +/** + * reentrantlock�������synchronized + * ����m1����this,ֻ��m1ִ����ϵ�ʱ��,m2����ִ�� + * �����Ǹ�ϰsynchronized��ԭʼ������ + * + * ʹ��reentrantlock�������ͬ���Ĺ��� + * ��Ҫע����ǣ�����Ҫ����Ҫ����Ҫ�ֶ��ͷ�������Ҫ������˵���飩 + * ʹ��syn�����Ļ���������쳣��jvm���Զ��ͷ���������lock�����ֶ��ͷ�������˾�����finally�н��������ͷ� + * @author mashibing + */ +package org.cc.thread.reentantlock; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class T02_ReentrantLock2 { + Lock lock = new ReentrantLock(); + + void m1() { + try { + lock.lock(); //synchronized(this) + for (int i = 0; i < 10; i++) { + TimeUnit.SECONDS.sleep(1); + + System.out.println(i); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + void m2() { + try { + lock.lock(); + System.out.println("m2 ..."); + } finally { + lock.unlock(); + } + + } + + public static void main(String[] args) { + T02_ReentrantLock2 rl = new T02_ReentrantLock2(); + new Thread(rl::m1).start(); + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + new Thread(rl::m2).start(); + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T03_ReentrantLock3.java b/src/main/java/org/cc/thread/reentantlock/T03_ReentrantLock3.java new file mode 100644 index 00000000..13207685 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T03_ReentrantLock3.java @@ -0,0 +1,72 @@ +/** + * reentrantlock�������synchronized + * ����m1����this,ֻ��m1ִ����ϵ�ʱ��,m2����ִ�� + * �����Ǹ�ϰsynchronized��ԭʼ������ + * + * ʹ��reentrantlock�������ͬ���Ĺ��� + * ��Ҫע����ǣ�����Ҫ����Ҫ����Ҫ�ֶ��ͷ�������Ҫ������˵���飩 + * ʹ��syn�����Ļ���������쳣��jvm���Զ��ͷ���������lock�����ֶ��ͷ�������˾�����finally�н��������ͷ� + * + * ʹ��reentrantlock���Խ��С�����������tryLock�������޷�������������ָ��ʱ�����޷��������߳̿��Ծ����Ƿ�����ȴ� + * @author mashibing + */ +package org.cc.thread.reentantlock; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class T03_ReentrantLock3 { + Lock lock = new ReentrantLock(); + + void m1() { + try { + lock.lock(); + for (int i = 0; i < 3; i++) { + TimeUnit.SECONDS.sleep(1); + + System.out.println(i); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + /** + * ʹ��tryLock���г�������������������񣬷�����������ִ�� + * ���Ը���tryLock�ķ���ֵ���ж��Ƿ����� + * Ҳ����ָ��tryLock��ʱ�䣬����tryLock(time)�׳��쳣������Ҫע��unclock�Ĵ�������ŵ�finally�� + */ + void m2() { + /* + boolean locked = lock.tryLock(); + System.out.println("m2 ..." + locked); + if(locked) lock.unlock(); + */ + + boolean locked = false; + + 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) { + T03_ReentrantLock3 rl = new T03_ReentrantLock3(); + new Thread(rl::m1).start(); + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + new Thread(rl::m2).start(); + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T04_ReentrantLock4.java b/src/main/java/org/cc/thread/reentantlock/T04_ReentrantLock4.java new file mode 100644 index 00000000..485b2519 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T04_ReentrantLock4.java @@ -0,0 +1,68 @@ +/** + * reentrantlock�������synchronized + * ����m1����this,ֻ��m1ִ����ϵ�ʱ��,m2����ִ�� + * �����Ǹ�ϰsynchronized��ԭʼ������ + * + * ʹ��reentrantlock�������ͬ���Ĺ��� + * ��Ҫע����ǣ�����Ҫ����Ҫ����Ҫ�ֶ��ͷ�������Ҫ������˵���飩 + * ʹ��syn�����Ļ���������쳣��jvm���Զ��ͷ���������lock�����ֶ��ͷ�������˾�����finally�н��������ͷ� + * + * ʹ��reentrantlock���Խ��С�����������tryLock�������޷�������������ָ��ʱ�����޷��������߳̿��Ծ����Ƿ�����ȴ� + * + * ʹ��ReentrantLock�����Ե���lockInterruptibly���������Զ��߳�interrupt����������Ӧ�� + * ��һ���̵߳ȴ����Ĺ����У����Ա���� + * + * @author mashibing + */ +package org.cc.thread.reentantlock; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Function; + +public class T04_ReentrantLock4 { + + public static void main(String[] args) { + Lock lock = new ReentrantLock(); + + + Thread t1 = new Thread(()->{ + try { + lock.lock(); + System.out.println("t1 start"); + TimeUnit.SECONDS.sleep(Integer.MAX_VALUE); + System.out.println("t1 end"); + } catch (InterruptedException e) { + System.out.println("interrupted!"); + } finally { + + lock.unlock(); + } + }); + t1.start(); + + Thread t2 = new Thread(()->{ + try { + //lock.lock(); + lock.lockInterruptibly(); //���Զ�interrupt()����������Ӧ + System.out.println("t2 start"); + TimeUnit.SECONDS.sleep(5); + System.out.println("t2 end"); + } catch (InterruptedException e) { + System.out.println("interrupted!"); + } finally { + lock.unlock(); + } + }); + t2.start(); + + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + t2.interrupt(); //����߳�2�ĵȴ� + + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T05_ReentrantLock5.java b/src/main/java/org/cc/thread/reentantlock/T05_ReentrantLock5.java new file mode 100644 index 00000000..f5dd24b7 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T05_ReentrantLock5.java @@ -0,0 +1,43 @@ +/** + * reentrantlock�������synchronized + * ����m1����this,ֻ��m1ִ����ϵ�ʱ��,m2����ִ�� + * �����Ǹ�ϰsynchronized��ԭʼ������ + * + * ʹ��reentrantlock�������ͬ���Ĺ��� + * ��Ҫע����ǣ�����Ҫ����Ҫ����Ҫ�ֶ��ͷ�������Ҫ������˵���飩 + * ʹ��syn�����Ļ���������쳣��jvm���Զ��ͷ���������lock�����ֶ��ͷ�������˾�����finally�н��������ͷ� + * + * ʹ��reentrantlock���Խ��С�����������tryLock�������޷�������������ָ��ʱ�����޷��������߳̿��Ծ����Ƿ�����ȴ� + * + * ʹ��ReentrantLock�����Ե���lockInterruptibly���������Զ��߳�interrupt����������Ӧ�� + * ��һ���̵߳ȴ����Ĺ����У����Ա���� + * + * ReentrantLock������ָ��Ϊ��ƽ�� + * + * @author mashibing + */ +package org.cc.thread.reentantlock; + +import java.util.concurrent.locks.ReentrantLock; + +public class T05_ReentrantLock5 extends Thread { + + private static ReentrantLock lock=new ReentrantLock(true); //����Ϊtrue��ʾΪ��ƽ������Ա������� + 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) { + T05_ReentrantLock5 rl=new T05_ReentrantLock5(); + Thread th1=new Thread(rl); + Thread th2=new Thread(rl); + th1.start(); + th2.start(); + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T06_TestCountDownLatch.java b/src/main/java/org/cc/thread/reentantlock/T06_TestCountDownLatch.java new file mode 100644 index 00000000..5ddbf576 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T06_TestCountDownLatch.java @@ -0,0 +1,60 @@ +package org.cc.thread.reentantlock; + +import java.util.concurrent.CountDownLatch; + +public class T06_TestCountDownLatch { + public static void main(String[] args) { + usingJoin(); + usingCountDownLatch(); + } + + private static void usingCountDownLatch() { + Thread[] threads = new Thread[100]; + CountDownLatch latch = new CountDownLatch(threads.length); + + for(int i=0; i{ + int result = 0; + for(int j=0; j<10000; j++) result += j; + latch.countDown(); + }); + } + + for (int i = 0; i < threads.length; i++) { + threads[i].start(); + } + + try { + latch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println("end latch"); + } + + private static void usingJoin() { + Thread[] threads = new Thread[100]; + + for(int i=0; i{ + int result = 0; + for(int j=0; j<10000; j++) result += j; + }); + } + + for (int i = 0; i < threads.length; i++) { + threads[i].start(); + } + + for (int i = 0; i < threads.length; i++) { + try { + threads[i].join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + System.out.println("end join"); + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T07_TestCyclicBarrier.java b/src/main/java/org/cc/thread/reentantlock/T07_TestCyclicBarrier.java new file mode 100644 index 00000000..ab16ab87 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T07_TestCyclicBarrier.java @@ -0,0 +1,36 @@ +package org.cc.thread.reentantlock; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class T07_TestCyclicBarrier { + public static void main(String[] args) { + //CyclicBarrier barrier = new CyclicBarrier(20); + +// CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println("满人,发车")); + + /**/ + CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() { + @Override + public void run() { + System.out.println("满人,发车"); + } + }); + + for(int i=0; i<100; i++) { + + new Thread(()->{ + try { + System.out.println(Thread.currentThread().getName()+"isdone"); + barrier.await(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (BrokenBarrierException e) { + e.printStackTrace(); + } + }).start(); + + } + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T08_TestPhaser.java b/src/main/java/org/cc/thread/reentantlock/T08_TestPhaser.java new file mode 100644 index 00000000..4b08c8e8 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T08_TestPhaser.java @@ -0,0 +1,88 @@ +package org.cc.thread.reentantlock; + +import java.util.Random; +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeUnit; + +public class T08_TestPhaser { + static Random r = new Random(); + static MarriagePhaser phaser = new MarriagePhaser(); + + static void milliSleep(int milli) { + try { + TimeUnit.MILLISECONDS.sleep(milli); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + + phaser.bulkRegister(5); + + for(int i=0; i<5; i++) { + final int nameIndex = i; + new Thread(()->{ + + Person p = new Person("person " + nameIndex); + p.arrive(); + phaser.arriveAndAwaitAdvance(); + + p.eat(); + phaser.arriveAndAwaitAdvance(); + + p.leave(); + phaser.arriveAndAwaitAdvance(); + }).start(); + } + + } + + + static class MarriagePhaser extends Phaser { + @Override + protected boolean onAdvance(int phase, int registeredParties) { + + switch (phase) { + case 0: + System.out.println("所有人到齐了!"); + return false; + case 1: + System.out.println("所有人吃完了!"); + return false; + case 2: + System.out.println("所有人离开了!"); + System.out.println("婚礼结束!"); + return true; + default: + return true; + } + } + } + + + static class Person { + String name; + + public Person(String name) { + this.name = name; + } + + public void arrive() { + milliSleep(r.nextInt(1000)); + System.out.printf("%s 到达现场!\n", name); + } + + public void eat() { + milliSleep(r.nextInt(1000)); + System.out.printf("%s 吃完!\n", name); + } + + public void leave() { + milliSleep(r.nextInt(1000)); + System.out.printf("%s 离开!\n", name); + } + } +} + + diff --git a/src/main/java/org/cc/thread/reentantlock/T09_TestPhaser2.java b/src/main/java/org/cc/thread/reentantlock/T09_TestPhaser2.java new file mode 100644 index 00000000..06df195d --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T09_TestPhaser2.java @@ -0,0 +1,120 @@ +package org.cc.thread.reentantlock; + +import java.util.Random; +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeUnit; + +public class T09_TestPhaser2 { + static Random r = new Random(); + static MarriagePhaser phaser = new MarriagePhaser(); + + + static void milliSleep(int milli) { + try { + TimeUnit.MILLISECONDS.sleep(milli); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + + phaser.bulkRegister(7); + + for(int i=0; i<5; i++) { + + new Thread(new Person("p" + i)).start(); + } + + new Thread(new Person("新郎")).start(); + new Thread(new Person("新娘")).start(); + + } + + + + static class MarriagePhaser extends Phaser { + @Override + protected boolean onAdvance(int phase, int registeredParties) { + + switch (phase) { + case 0: + System.out.println("所有人到齐了!" + registeredParties); + System.out.println(); + return false; + case 1: + System.out.println("所有人吃完了!" + registeredParties); + System.out.println(); + return false; + case 2: + System.out.println("所有人离开了!" + registeredParties); + System.out.println(); + return false; + case 3: + System.out.println("婚礼结束!新郎新娘抱抱!" + registeredParties); + return true; + default: + return true; + } + } + } + + + static class Person implements Runnable { + String name; + + public Person(String name) { + this.name = name; + } + + public void arrive() { + + milliSleep(r.nextInt(1000)); + System.out.printf("%s 到达现场!\n", name); + phaser.arriveAndAwaitAdvance(); + } + + public void eat() { + milliSleep(r.nextInt(1000)); + System.out.printf("%s 吃完!\n", name); + phaser.arriveAndAwaitAdvance(); + } + + public void leave() { + milliSleep(r.nextInt(1000)); + System.out.printf("%s 离开!\n", name); + + + phaser.arriveAndAwaitAdvance(); + } + + + private void hug() { + if(name.equals("新郎") || name.equals("新娘")) { + milliSleep(r.nextInt(1000)); + System.out.printf("%s 洞房!\n", name); + phaser.arriveAndAwaitAdvance(); + } else { + phaser.arriveAndDeregister(); + //phaser.register() + } + } + + @Override + public void run() { + arrive(); + + + eat(); + + + leave(); + + + hug(); + + } + } +} + + diff --git a/src/main/java/org/cc/thread/reentantlock/T10_TestReadWriteLock.java b/src/main/java/org/cc/thread/reentantlock/T10_TestReadWriteLock.java new file mode 100644 index 00000000..fc327eb8 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T10_TestReadWriteLock.java @@ -0,0 +1,61 @@ +package org.cc.thread.reentantlock; + +import java.util.Random; +import java.util.concurrent.atomic.LongAdder; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class T10_TestReadWriteLock { + static Lock lock = new ReentrantLock(); + private static int value; + + static ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); + static Lock readLock = readWriteLock.readLock(); + static Lock writeLock = readWriteLock.writeLock(); + + public static void read(Lock lock) { + try { + lock.lock(); + Thread.sleep(1000); + System.out.println("read over!"); + //模拟读取操作 + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + public static void write(Lock lock, int v) { + try { + lock.lock(); + Thread.sleep(1000); + value = v; + System.out.println("write over!"); + //模拟写操作 + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + + + + + public static void main(String[] args) { + //Runnable readR = ()-> read(lock); + Runnable readR = ()-> read(readLock); + + //Runnable writeR = ()->write(lock, new Random().nextInt()); + Runnable writeR = ()->write(writeLock, new Random().nextInt()); + + for(int i=0; i<18; i++) new Thread(readR).start(); + for(int i=0; i<2; i++) new Thread(writeR).start(); + + + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T11_TestSemaphore.java b/src/main/java/org/cc/thread/reentantlock/T11_TestSemaphore.java new file mode 100644 index 00000000..51a54d43 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T11_TestSemaphore.java @@ -0,0 +1,41 @@ +package org.cc.thread.reentantlock; + +import java.util.concurrent.Semaphore; + +public class T11_TestSemaphore { + public static void main(String[] args) { + //Semaphore s = new Semaphore(2); +// Semaphore s = new Semaphore(2, true); + //允许一个线程同时执行 + Semaphore s = new Semaphore(1); + + new Thread(()->{ + try { + s.acquire(); + + System.out.println("T1 running...start"); + Thread.sleep(2000); + System.out.println("T1 running...end"); + + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + s.release(); + } + }).start(); + + new Thread(()->{ + try { + s.acquire(); + + System.out.println("T2 running...start"); + Thread.sleep(2000); + System.out.println("T2 running...end"); + + s.release(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T12_TestExchanger.java b/src/main/java/org/cc/thread/reentantlock/T12_TestExchanger.java new file mode 100644 index 00000000..7ae7b6cf --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T12_TestExchanger.java @@ -0,0 +1,47 @@ +package org.cc.thread.reentantlock; + +import java.util.concurrent.Exchanger; + +public class T12_TestExchanger { + + static Exchanger exchanger = new Exchanger<>(); + + public static void main(String[] args) { + new Thread(()->{ + String s = "T1"; + try { + s = exchanger.exchange(s); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName() + " " + s); + + }, "t1").start(); + + + new Thread(()->{ + String s = "T2"; + try { + s = exchanger.exchange(s); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName() + " " + s); + + }, "t2").start(); + + +// new Thread(()->{ +// String s = "T3"; +// try { +// s = exchanger.exchange(s); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// System.out.println(Thread.currentThread().getName() + " " + s); +// +// }, "t3").start(); + + + } +} diff --git a/src/main/java/org/cc/thread/reentantlock/T13_TestLockSupport.java b/src/main/java/org/cc/thread/reentantlock/T13_TestLockSupport.java new file mode 100644 index 00000000..4b48cca7 --- /dev/null +++ b/src/main/java/org/cc/thread/reentantlock/T13_TestLockSupport.java @@ -0,0 +1,36 @@ +package org.cc.thread.reentantlock; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; + +public class T13_TestLockSupport { + public static void main(String[] args) { + Thread t = new Thread(()->{ + for (int i = 0; i < 10; i++) { + System.out.println(i); + if(i == 5) { + LockSupport.park(); + } + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }); + + t.start(); + + LockSupport.unpark(t); + + /*try { + TimeUnit.SECONDS.sleep(8); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("after 8 senconds!"); + + LockSupport.unpark(t);*/ + + } +} From f957fc06f44560ee67d6716c8300a2c56f9450cf Mon Sep 17 00:00:00 2001 From: chen88358323 Date: Tue, 16 May 2023 15:42:02 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A9=AC=E5=A3=AB?= =?UTF-8?q?=E5=85=B5=20=E7=BA=BF=E7=A8=8B=E8=AF=BE=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 24 +++ .../twophasetermination/MonitorTest.java | 58 ++++++ .../com/tuling/jucdemo/atomic/ABATest.java | 49 +++++ .../atomic/AtomicIntegerArrayTest.java | 24 +++ .../atomic/AtomicIntegerFieldUpdaterTest.java | 50 +++++ .../jucdemo/atomic/AtomicIntegerTest.java | 35 ++++ .../jucdemo/atomic/AtomicReferenceTest.java | 40 ++++ .../atomic/AtomicStampedReferenceTest.java | 55 +++++ .../com/tuling/jucdemo/atomic/CASTest.java | 38 ++++ .../jucdemo/atomic/LongAccumulatorTest.java | 25 +++ .../tuling/jucdemo/atomic/LongAdderTest.java | 72 +++++++ .../tuling/jucdemo/factory/UnsafeFactory.java | 43 ++++ .../java/com/tuling/jucdemo/go/channel.go | 23 +++ src/main/java/com/tuling/jucdemo/go/hello.go | 19 ++ .../tuling/jucdemo/jmm/FalseSharingTest.java | 52 +++++ .../tuling/jucdemo/jmm/FinalFieldExample.java | 32 +++ .../com/tuling/jucdemo/jmm/ReOrderTest.java | 65 ++++++ .../tuling/jucdemo/jmm/SingletonFactory.java | 32 +++ .../java/com/tuling/jucdemo/jmm/Test.java | 58 ++++++ .../tuling/jucdemo/jmm/VisibilityTest.java | 95 +++++++++ .../com/tuling/jucdemo/jmm/VolatileTest2.java | 33 +++ .../java/com/tuling/jucdemo/lock/CASLock.java | 38 ++++ .../com/tuling/jucdemo/lock/TulingLock.java | 44 ++++ .../com/tuling/jucdemo/sync/SyncWaitTest.java | 46 +++++ .../jucdemo/threadactiveness/Chopstick.java | 20 ++ .../threadactiveness/DeadLockTest.java | 44 ++++ .../jucdemo/threadactiveness/HungryTest.java | 76 +++++++ .../threadactiveness/LiveLockTest.java | 113 +++++++++++ .../jucdemo/threadactiveness/Philosopher.java | 65 ++++++ .../threadactiveness/PhilosopherEatTest.java | 23 +++ .../jucdemo/threadbase/LockSupportTest.java | 26 +++ .../jucdemo/threadbase/ParkUnparkDemo.java | 99 +++++++++ .../tuling/jucdemo/threadbase/PipedTest.java | 45 +++++ .../jucdemo/threadbase/SellTicketDemo.java | 54 +++++ .../jucdemo/threadbase/ThreadExecuteTest.java | 88 ++++++++ .../threadbase/ThreadInterruptTest.java | 45 +++++ .../jucdemo/threadbase/ThreadJoinDemo.java | 27 +++ .../jucdemo/threadbase/ThreadStateTest.java | 28 +++ .../jucdemo/threadbase/ThreadStopDemo.java | 42 ++++ .../jucdemo/threadbase/ThreadStopDemo2.java | 32 +++ .../jucdemo/threadbase/VolatileDemo.java | 33 +++ .../tuling/jucdemo/threadbase/WaitDemo.java | 51 +++++ .../java/org/cc/leetcode/ListNodeRevseve.java | 68 +++++++ src/main/java/org/cc/leetcode/TwoSplite.java | 64 ++++++ .../org/cc/leetcode/onehundred/Num18.java | 40 ---- .../org/cc/leetcode/onehundred/Num55.java | 78 ++++++++ .../org/cc/leetcode/onehundred/Num56.java | 148 ++++++++++++++ .../org/cc/leetcode/onehundred/Num57.java | 187 +++++++++++++++++ .../cc/leetcode/onehundred/thirsty/Num21.java | 63 ++++++ .../cc/leetcode/onehundred/thirsty/Num23.java | 106 ++++++++++ .../cc/leetcode/onehundred/thirsty/Num24.java | 86 ++++++++ .../cc/leetcode/onehundred/thirsty/Num25.java | 189 ++++++++++++++++++ .../onehundred/{ => twenty}/Num11.java | 2 +- .../cc/leetcode/onehundred/twenty/Num12.java | 119 +++++++++++ .../cc/leetcode/onehundred/twenty/Num13.java | 141 +++++++++++++ .../onehundred/{ => twenty}/Num14.java | 2 +- .../onehundred/{ => twenty}/Num15.java | 106 ++++------ .../cc/leetcode/onehundred/twenty/Num16.java | 101 ++++++++++ .../cc/leetcode/onehundred/twenty/Num17.java | 139 +++++++++++++ .../cc/leetcode/onehundred/twenty/Num18.java | 72 +++++++ .../cc/leetcode/onehundred/twenty/Num19.java | 132 ++++++++++++ .../java/org/cc/leetcode/util/ListNode.java | 15 +- .../org/cc/thread/aqs/tulingfox/CASLock.java | 38 ++++ .../thread/aqs/tulingfox/ConditionTest.java | 52 +++++ .../aqs/tulingfox/ReentrantLockDemo.java | 39 ++++ .../aqs/tulingfox/ReentrantLockDemo2.java | 47 +++++ .../aqs/tulingfox/ReentrantLockDemo3.java | 51 +++++ .../aqs/tulingfox/ReentrantLockDemo4.java | 59 ++++++ .../aqs/tulingfox/ReentrantLockDemo5.java | 51 +++++ .../aqs/tulingfox/ReentrantLockDemo6.java | 97 +++++++++ .../cc/thread/aqs/tulingfox/TulingLock.java | 46 +++++ 71 files changed, 4192 insertions(+), 107 deletions(-) create mode 100644 src/main/java/com/tuling/designpattern/twophasetermination/MonitorTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/ABATest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerArrayTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerFieldUpdaterTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/AtomicReferenceTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/AtomicStampedReferenceTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/CASTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/LongAccumulatorTest.java create mode 100644 src/main/java/com/tuling/jucdemo/atomic/LongAdderTest.java create mode 100644 src/main/java/com/tuling/jucdemo/factory/UnsafeFactory.java create mode 100644 src/main/java/com/tuling/jucdemo/go/channel.go create mode 100644 src/main/java/com/tuling/jucdemo/go/hello.go create mode 100644 src/main/java/com/tuling/jucdemo/jmm/FalseSharingTest.java create mode 100644 src/main/java/com/tuling/jucdemo/jmm/FinalFieldExample.java create mode 100644 src/main/java/com/tuling/jucdemo/jmm/ReOrderTest.java create mode 100644 src/main/java/com/tuling/jucdemo/jmm/SingletonFactory.java create mode 100644 src/main/java/com/tuling/jucdemo/jmm/Test.java create mode 100644 src/main/java/com/tuling/jucdemo/jmm/VisibilityTest.java create mode 100644 src/main/java/com/tuling/jucdemo/jmm/VolatileTest2.java create mode 100644 src/main/java/com/tuling/jucdemo/lock/CASLock.java create mode 100644 src/main/java/com/tuling/jucdemo/lock/TulingLock.java create mode 100644 src/main/java/com/tuling/jucdemo/sync/SyncWaitTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadactiveness/Chopstick.java create mode 100644 src/main/java/com/tuling/jucdemo/threadactiveness/DeadLockTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadactiveness/HungryTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadactiveness/LiveLockTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadactiveness/Philosopher.java create mode 100644 src/main/java/com/tuling/jucdemo/threadactiveness/PhilosopherEatTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/LockSupportTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/ParkUnparkDemo.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/PipedTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/SellTicketDemo.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/ThreadExecuteTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/ThreadInterruptTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/ThreadJoinDemo.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/ThreadStateTest.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo2.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/VolatileDemo.java create mode 100644 src/main/java/com/tuling/jucdemo/threadbase/WaitDemo.java create mode 100644 src/main/java/org/cc/leetcode/ListNodeRevseve.java create mode 100644 src/main/java/org/cc/leetcode/TwoSplite.java delete mode 100644 src/main/java/org/cc/leetcode/onehundred/Num18.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/Num55.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/Num56.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/Num57.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/thirsty/Num21.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/thirsty/Num23.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/thirsty/Num24.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/thirsty/Num25.java rename src/main/java/org/cc/leetcode/onehundred/{ => twenty}/Num11.java (97%) create mode 100644 src/main/java/org/cc/leetcode/onehundred/twenty/Num12.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/twenty/Num13.java rename src/main/java/org/cc/leetcode/onehundred/{ => twenty}/Num14.java (98%) rename src/main/java/org/cc/leetcode/onehundred/{ => twenty}/Num15.java (60%) create mode 100644 src/main/java/org/cc/leetcode/onehundred/twenty/Num16.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/twenty/Num17.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/twenty/Num18.java create mode 100644 src/main/java/org/cc/leetcode/onehundred/twenty/Num19.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/CASLock.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/ConditionTest.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo2.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo3.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo4.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo5.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo6.java create mode 100644 src/main/java/org/cc/thread/aqs/tulingfox/TulingLock.java diff --git a/pom.xml b/pom.xml index e997508b..48a1725d 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,30 @@ gson 2.9.0 + + org.projectlombok + lombok + RELEASE + compile + + + ch.qos.logback + logback-classic + 1.2.3 + + + org.slf4j + slf4j-log4j12 + 1.7.22 + + + + + + commons-lang + commons-lang + 2.6 + diff --git a/src/main/java/com/tuling/designpattern/twophasetermination/MonitorTest.java b/src/main/java/com/tuling/designpattern/twophasetermination/MonitorTest.java new file mode 100644 index 00000000..79eea16e --- /dev/null +++ b/src/main/java/com/tuling/designpattern/twophasetermination/MonitorTest.java @@ -0,0 +1,58 @@ +package com.tuling.designpattern.twophasetermination; + +/** + * @author Fox + */ +public class MonitorTest { + boolean started = false; + //采集线程 + Thread rptThread; + + //启动采集功能 + synchronized void start() { + //不允许同时启动多个采集线程 + if (started) { + return; + } + started = true; + rptThread = new Thread(() -> { + while (!Thread.currentThread().isInterrupted()) { + //省略采集、回传实现 + report(); + //每隔两秒钟采集、回传一次数据 + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + //重新设置线程中断状态 + Thread.currentThread().interrupt(); + } + } + //执行到此处说明线程马上终止 + started = false; + }); + rptThread.start(); + } + + private void report() { + System.out.println("采集数据"); + } + + //终止采集功能 + synchronized void stop() { + rptThread.interrupt(); + } + + + public static void main(String[] args) { + MonitorTest monitor = new MonitorTest(); + monitor.start(); + + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + monitor.stop(); + } + +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/ABATest.java b/src/main/java/com/tuling/jucdemo/atomic/ABATest.java new file mode 100644 index 00000000..f3c15111 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/ABATest.java @@ -0,0 +1,49 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.LockSupport; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + */ +@Slf4j +public class ABATest { + + public static void main(String[] args) { + AtomicInteger atomicInteger = new AtomicInteger(1); + + new Thread(()->{ + int value = atomicInteger.get(); + log.debug("Thread1 read value: " + value); + + // 阻塞1s + LockSupport.parkNanos(1000000000L); + + // Thread1通过CAS修改value值为3 + if (atomicInteger.compareAndSet(value, 3)) { + log.debug("Thread1 update from " + value + " to 3"); + } else { + log.debug("Thread1 update fail!"); + } + },"Thread1").start(); + + new Thread(()->{ + int value = atomicInteger.get(); + log.debug("Thread2 read value: " + value); + // Thread2通过CAS修改value值为2 + if (atomicInteger.compareAndSet(value, 2)) { + log.debug("Thread2 update from " + value + " to 2"); + + // do something + value = atomicInteger.get(); + log.debug("Thread2 read value: " + value); + // Thread2通过CAS修改value值为1 + if (atomicInteger.compareAndSet(value, 1)) { + log.debug("Thread2 update from " + value + " to 1"); + } + } + },"Thread2").start(); + } +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerArrayTest.java b/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerArrayTest.java new file mode 100644 index 00000000..18d0c5b7 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerArrayTest.java @@ -0,0 +1,24 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.atomic.AtomicIntegerArray; + +/** + * @author Fox + */ +public class AtomicIntegerArrayTest { + + static int[] value = new int[]{ 1, 2, 3, 4, 5 }; + static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(value); + + + public static void main(String[] args) throws InterruptedException { + + //设置索引0的元素为100 + atomicIntegerArray.set(0, 100); + System.out.println(atomicIntegerArray.get(0)); + //以原子更新的方式将数组中索引为1的元素与输入值相加 + atomicIntegerArray.getAndAdd(1,5); + + System.out.println(atomicIntegerArray); + } +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerFieldUpdaterTest.java b/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerFieldUpdaterTest.java new file mode 100644 index 00000000..3d0acfcb --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerFieldUpdaterTest.java @@ -0,0 +1,50 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +/** + * @author Fox + */ +public class AtomicIntegerFieldUpdaterTest { + + + public static class Candidate { + //字段必须是volatile类型 + volatile int score = 0; + + AtomicInteger score2 = new AtomicInteger(); + } + + public static final AtomicIntegerFieldUpdater scoreUpdater = + AtomicIntegerFieldUpdater.newUpdater(Candidate.class, "score"); + + public static AtomicInteger realScore = new AtomicInteger(0); + + public static void main(String[] args) throws InterruptedException { + + final Candidate candidate = new Candidate(); + + Thread[] t = new Thread[10000]; + for (int i = 0; i < 10000; i++) { + t[i] = new Thread(new Runnable() { + @Override + public void run() { + if (Math.random() > 0.4) { + candidate.score2.incrementAndGet(); + scoreUpdater.incrementAndGet(candidate); + realScore.incrementAndGet(); + } + } + }); + t[i].start(); + } + for (int i = 0; i < 10000; i++) { + t[i].join(); + } + System.out.println("AtomicIntegerFieldUpdater Score=" + candidate.score); + System.out.println("AtomicInteger Score=" + candidate.score2.get()); + System.out.println("realScore=" + realScore.get()); + + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerTest.java b/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerTest.java new file mode 100644 index 00000000..52c73b79 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/AtomicIntegerTest.java @@ -0,0 +1,35 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author Fox + */ +public class AtomicIntegerTest { + + static AtomicInteger sum = new AtomicInteger(0); + + public static void main(String[] args) { + + for (int i = 0; i < 10; i++) { + Thread thread = new Thread(() -> { + for (int j = 0; j < 10000; j++) { + // 原子自增 CAS + sum.incrementAndGet(); + //count++; + + } + }); + thread.start(); + } + + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(sum.get()); + + } + +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/AtomicReferenceTest.java b/src/main/java/com/tuling/jucdemo/atomic/AtomicReferenceTest.java new file mode 100644 index 00000000..74751261 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/AtomicReferenceTest.java @@ -0,0 +1,40 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.atomic.AtomicReference; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author Fox + */ +public class AtomicReferenceTest { + + public static void main( String[] args ) { + User user1 = new User("张三", 23); + User user2 = new User("李四", 25); + User user3 = new User("王五", 20); + + //初始化为 user1 + AtomicReference atomicReference = new AtomicReference<>(); + atomicReference.set(user1); + + //把 user2 赋给 atomicReference + atomicReference.compareAndSet(user1, user2); + System.out.println(atomicReference.get()); + + //把 user3 赋给 atomicReference + atomicReference.compareAndSet(user1, user3); + System.out.println(atomicReference.get()); + + } + +} + + +@Data +@AllArgsConstructor +class User { + private String name; + private Integer age; +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/AtomicStampedReferenceTest.java b/src/main/java/com/tuling/jucdemo/atomic/AtomicStampedReferenceTest.java new file mode 100644 index 00000000..06c854b4 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/AtomicStampedReferenceTest.java @@ -0,0 +1,55 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.atomic.AtomicStampedReference; +import java.util.concurrent.locks.LockSupport; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + */ +@Slf4j +public class AtomicStampedReferenceTest { + + public static void main(String[] args) { + // 定义AtomicStampedReference Pair.reference值为1, Pair.stamp为1 + AtomicStampedReference atomicStampedReference = new AtomicStampedReference(1,1); + + new Thread(()->{ + int[] stampHolder = new int[1]; + int value = (int) atomicStampedReference.get(stampHolder); + int stamp = stampHolder[0]; + log.debug("Thread1 read value: " + value + ", stamp: " + stamp); + + // 阻塞1s + LockSupport.parkNanos(1000000000L); + // Thread1通过CAS修改value值为3 stamp是版本,每次修改可以通过+1保证版本唯一性 + if (atomicStampedReference.compareAndSet(value, 3,stamp,stamp+1)) { + log.debug("Thread1 update from " + value + " to 3"); + } else { + log.debug("Thread1 update fail!"); + } + },"Thread1").start(); + + new Thread(()->{ + int[] stampHolder = new int[1]; + int value = (int)atomicStampedReference.get(stampHolder); + int stamp = stampHolder[0]; + log.debug("Thread2 read value: " + value+ ", stamp: " + stamp); + // Thread2通过CAS修改value值为2 + if (atomicStampedReference.compareAndSet(value, 2,stamp,stamp+1)) { + log.debug("Thread2 update from " + value + " to 2"); + + // do something + + value = (int) atomicStampedReference.get(stampHolder); + stamp = stampHolder[0]; + log.debug("Thread2 read value: " + value+ ", stamp: " + stamp); + // Thread2通过CAS修改value值为1 + if (atomicStampedReference.compareAndSet(value, 1,stamp,stamp+1)) { + log.debug("Thread2 update from " + value + " to 1"); + } + } + },"Thread2").start(); + } +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/CASTest.java b/src/main/java/com/tuling/jucdemo/atomic/CASTest.java new file mode 100644 index 00000000..a6476c97 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/CASTest.java @@ -0,0 +1,38 @@ +package com.tuling.jucdemo.atomic; + +import com.tuling.jucdemo.factory.UnsafeFactory; +import sun.misc.Unsafe; + +/** + * @author Fox + */ +public class CASTest { + + public static void main(String[] args) { + Entity entity = new Entity(); + + Unsafe unsafe = UnsafeFactory.getUnsafe(); + + long offset = UnsafeFactory.getFieldOffset(unsafe, Entity.class, "x"); + System.out.println(offset); + boolean successful; + + // 4个参数分别是:对象实例、字段的内存偏移量、字段期望值、字段更新值 + successful = unsafe.compareAndSwapInt(entity, offset, 0, 3); + System.out.println(successful + "\t" + entity.x); + + successful = unsafe.compareAndSwapInt(entity, offset, 3, 5); + System.out.println(successful + "\t" + entity.x); + + successful = unsafe.compareAndSwapInt(entity, offset, 3, 8); + System.out.println(successful + "\t" + entity.x); + + } + + +} + + +class Entity{ + int x; +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/LongAccumulatorTest.java b/src/main/java/com/tuling/jucdemo/atomic/LongAccumulatorTest.java new file mode 100644 index 00000000..41876a6d --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/LongAccumulatorTest.java @@ -0,0 +1,25 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.LongAccumulator; +import java.util.stream.IntStream; + +/** + * @author Fox + */ +public class LongAccumulatorTest { + + public static void main(String[] args) throws InterruptedException { + // 累加 x+y + LongAccumulator accumulator = new LongAccumulator((x, y) -> x + y, 0); + + ExecutorService executor = Executors.newFixedThreadPool(8); + // 1到9累加 + IntStream.range(1, 10).forEach(i -> executor.submit(() -> accumulator.accumulate(i))); + + Thread.sleep(2000); + System.out.println(accumulator.getThenReset()); + + } +} diff --git a/src/main/java/com/tuling/jucdemo/atomic/LongAdderTest.java b/src/main/java/com/tuling/jucdemo/atomic/LongAdderTest.java new file mode 100644 index 00000000..e74c28ac --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/atomic/LongAdderTest.java @@ -0,0 +1,72 @@ +package com.tuling.jucdemo.atomic; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.LongAdder; + +/** + * @author Fox + */ +public class LongAdderTest { + + public static void main(String[] args) { + testAtomicLongVSLongAdder(10, 10000); + System.out.println("=================="); + testAtomicLongVSLongAdder(10, 200000); + System.out.println("=================="); + testAtomicLongVSLongAdder(100, 200000); + } + + static void testAtomicLongVSLongAdder(final int threadCount, final int times) { + try { + long start = System.currentTimeMillis(); + testLongAdder(threadCount, times); + long end = System.currentTimeMillis() - start; + System.out.println("条件>>>>>>线程数:" + threadCount + ", 单线程操作计数" + times); + System.out.println("结果>>>>>>LongAdder方式增加计数" + (threadCount * times) + "次,共计耗时:" + end); + + long start2 = System.currentTimeMillis(); + testAtomicLong(threadCount, times); + long end2 = System.currentTimeMillis() - start2; + System.out.println("条件>>>>>>线程数:" + threadCount + ", 单线程操作计数" + times); + System.out.println("结果>>>>>>AtomicLong方式增加计数" + (threadCount * times) + "次,共计耗时:" + end2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + static void testAtomicLong(final int threadCount, final int times) throws InterruptedException { + CountDownLatch countDownLatch = new CountDownLatch(threadCount); + AtomicLong atomicLong = new AtomicLong(); + for (int i = 0; i < threadCount; i++) { + new Thread(new Runnable() { + @Override + public void run() { + for (int j = 0; j < times; j++) { + atomicLong.incrementAndGet(); + } + countDownLatch.countDown(); + } + }, "my-thread" + i).start(); + } + countDownLatch.await(); + } + + static void testLongAdder(final int threadCount, final int times) throws InterruptedException { + CountDownLatch countDownLatch = new CountDownLatch(threadCount); + LongAdder longAdder = new LongAdder(); + for (int i = 0; i < threadCount; i++) { + new Thread(new Runnable() { + @Override + public void run() { + for (int j = 0; j < times; j++) { + longAdder.add(1); + } + countDownLatch.countDown(); + } + }, "my-thread" + i).start(); + } + + countDownLatch.await(); + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/factory/UnsafeFactory.java b/src/main/java/com/tuling/jucdemo/factory/UnsafeFactory.java new file mode 100644 index 00000000..30d34d77 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/factory/UnsafeFactory.java @@ -0,0 +1,43 @@ +package com.tuling.jucdemo.factory; + +import java.lang.reflect.Field; + +import sun.misc.Unsafe; + +/** + * @author Fox + */ +public class UnsafeFactory { + + /** + * 获取 Unsafe 对象 + * @return + */ + public static Unsafe getUnsafe() { + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + return (Unsafe) field.get(null); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 获取字段的内存偏移量 + * @param unsafe + * @param clazz + * @param fieldName + * @return + */ + public static long getFieldOffset(Unsafe unsafe, Class clazz, String fieldName) { + try { + return unsafe.objectFieldOffset(clazz.getDeclaredField(fieldName)); + } catch (NoSuchFieldException e) { + throw new Error(e); + } + } + + +} diff --git a/src/main/java/com/tuling/jucdemo/go/channel.go b/src/main/java/com/tuling/jucdemo/go/channel.go new file mode 100644 index 00000000..2a92a173 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/go/channel.go @@ -0,0 +1,23 @@ +package main + +import "fmt" + +func sum(s []int, c chan int) { + sum := 0 + for _, v := range s { + sum += v + } + c <- sum // 把 sum 发送到通道 c +} + +func main() { + s := []int{7, 2, 8, -9, 4, 0} + + c := make(chan int) + go sum(s[:len(s)/2], c) + go sum(s[len(s)/2:], c) + x, y := <-c, <-c // 从通道 c 中接收 + + fmt.Println(x, y, x+y) + +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/go/hello.go b/src/main/java/com/tuling/jucdemo/go/hello.go new file mode 100644 index 00000000..39da55ee --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/go/hello.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "time" +) + +func say(s string) { + for i := 0; i < 5; i++ { + time.Sleep(100 * time.Millisecond) + fmt.Println(s) + } +} + +func main() { + // 开启 goroutine 轻量级线程 + go say("world") + say("hello") +} diff --git a/src/main/java/com/tuling/jucdemo/jmm/FalseSharingTest.java b/src/main/java/com/tuling/jucdemo/jmm/FalseSharingTest.java new file mode 100644 index 00000000..ccbd415b --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/jmm/FalseSharingTest.java @@ -0,0 +1,52 @@ +package com.tuling.jucdemo.jmm; + +import sun.misc.Contended; + +/** + * 伪共享 + */ +public class FalseSharingTest { + + public static void main(String[] args) throws InterruptedException { + testPointer(new Pointer()); + } + + private static void testPointer(Pointer pointer) throws InterruptedException { + long start = System.currentTimeMillis(); + Thread t1 = new Thread(() -> { + for (int i = 0; i < 100000000; i++) { + pointer.x++; + } + }); + + Thread t2 = new Thread(() -> { + for (int i = 0; i < 100000000; i++) { + pointer.y++; + } + }); + + t1.start(); + t2.start(); + t1.join(); + t2.join(); + // 思考:x,y是线程安全的吗? + System.out.println(pointer.x+","+pointer.y); + + System.out.println(System.currentTimeMillis() - start); + + + } +} + + +class Pointer { + // 避免伪共享: @Contended + jvm参数:-XX:-RestrictContended jdk8支持 + @Contended + volatile long x; + //避免伪共享: 缓存行填充 + //long p1, p2, p3, p4, p5, p6, p7; + volatile long y; +} + + + diff --git a/src/main/java/com/tuling/jucdemo/jmm/FinalFieldExample.java b/src/main/java/com/tuling/jucdemo/jmm/FinalFieldExample.java new file mode 100644 index 00000000..26f02a21 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/jmm/FinalFieldExample.java @@ -0,0 +1,32 @@ +package com.tuling.jucdemo.jmm; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * + * https://docs.oracle.com/javase/specs/jls/se14/html/jls-17.html#jls-17.5 + */ +public class FinalFieldExample { + final int x; + int y; + static FinalFieldExample f; + + public FinalFieldExample() { + x = 3; + y = 4; + } + + static void writer() { + f = new FinalFieldExample(); + } + + static void reader() { + if (f != null) { + int i = f.x; // guaranteed to see 3 + int j = f.y; // could see 0 + } + + } + +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/jmm/ReOrderTest.java b/src/main/java/com/tuling/jucdemo/jmm/ReOrderTest.java new file mode 100644 index 00000000..dc81ea04 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/jmm/ReOrderTest.java @@ -0,0 +1,65 @@ +package com.tuling.jucdemo.jmm; + +import com.tuling.jucdemo.factory.UnsafeFactory; + +/** + * @author Fox + * + */ +public class ReOrderTest { + + private static int x = 0, y = 0; + private volatile static int a = 0, b = 0; + + public static void main(String[] args) throws InterruptedException { + int i=0; + while (true) { + i++; + x = 0; + y = 0; + a = 0; + b = 0; + + /** + * x,y: 00, 10, 01, 11 + */ + Thread thread1 = new Thread(new Runnable() { + @Override + public void run() { + shortWait(20000); + a = 1; // volatile写 + // StoreLoad + //UnsafeFactory.getUnsafe().storeFence(); + x = b; // volatile读 + } + }); + Thread thread2 = new Thread(new Runnable() { + @Override + public void run() { + b = 1; + //UnsafeFactory.getUnsafe().storeFence(); + y = a; + } + }); + + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + System.out.println("第" + i + "次(" + x + "," + y + ")"); + if (x==0&&y==0){ + break; + } + } + } + + public static void shortWait(long interval){ + long start = System.nanoTime(); + long end; + do{ + end = System.nanoTime(); + }while(start + interval >= end); + } + +} diff --git a/src/main/java/com/tuling/jucdemo/jmm/SingletonFactory.java b/src/main/java/com/tuling/jucdemo/jmm/SingletonFactory.java new file mode 100644 index 00000000..9b0890c3 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/jmm/SingletonFactory.java @@ -0,0 +1,32 @@ +package com.tuling.jucdemo.jmm; + +/** + * @author Fox + * hsdis-amd64.dll + * 查看汇编指令 + * -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp + * DCL为什么要使用volatile + */ +public class SingletonFactory { + + private static SingletonFactory myInstance; + + public static SingletonFactory getMyInstance() { + if (myInstance == null) { + synchronized (SingletonFactory.class) { + if (myInstance == null) { + // 1. 开辟一片内存空间 + + // 3. myInstance指向内存空间的地址 + // 2. 对象初始化 + myInstance = new SingletonFactory(); + } + } + } + return myInstance; + } + + public static void main(String[] args) { + SingletonFactory.getMyInstance(); + } +} diff --git a/src/main/java/com/tuling/jucdemo/jmm/Test.java b/src/main/java/com/tuling/jucdemo/jmm/Test.java new file mode 100644 index 00000000..501ed735 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/jmm/Test.java @@ -0,0 +1,58 @@ +package com.tuling.jucdemo.jmm; + +import java.util.concurrent.locks.ReentrantLock; + +import com.tuling.jucdemo.lock.CASLock; + +/** + * @author Fox + */ +public class Test { + private volatile static int sum = 0; + static Object object = ""; + static ReentrantLock lock = new ReentrantLock(); + + static CASLock casLock = new CASLock(); + + public static void main(String[] args) { + + for (int i = 0; i < 10; i++) { + Thread thread = new Thread(() -> { + //synchronized (object) { + //lock.lock(); + // + for(;;){ + //state=0 + if(casLock.getState()==0&&casLock.cas()) { + try { + for (int j = 0; j < 10000; j++) { + sum++; + } + // + System.out.println(casLock.getState()); + } finally { + //lock.unlock(); + // state=0 + casLock.setState(0); + } + break; + } + } + + //} + }); + thread.start(); + } + + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + System.out.println(sum); + + } + + +} diff --git a/src/main/java/com/tuling/jucdemo/jmm/VisibilityTest.java b/src/main/java/com/tuling/jucdemo/jmm/VisibilityTest.java new file mode 100644 index 00000000..af625bd7 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/jmm/VisibilityTest.java @@ -0,0 +1,95 @@ +package com.tuling.jucdemo.jmm; + + +import java.util.concurrent.locks.LockSupport; + +import com.tuling.jucdemo.factory.UnsafeFactory; + +/** + * @author Fox + * + * -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp + * hsdis-amd64.dll + * 可见性案例 + */ +public class VisibilityTest { + // storeLoad JVM内存屏障 ----> (汇编层面指令) lock; addl $0,0(%%rsp) + // lock前缀指令不是内存屏障的指令,但是有内存屏障的效果 缓存失效 + private boolean flag = true; + private int count = 0; + + public void refresh() { + // threadB对flag的写操作会 happens-before threadA对flag的读操作 + flag = false; + System.out.println(Thread.currentThread().getName() + "修改flag:"+flag); + } + + public void load() { + System.out.println(Thread.currentThread().getName() + "开始执行....."); + while (flag) { + //TODO 业务逻辑 + count++; + //JMM模型 内存模型: 线程间通信有关 共享内存模型 + //没有跳出循环 可见性的问题 + //能够跳出循环 内存屏障 + //UnsafeFactory.getUnsafe().storeFence(); + //能够跳出循环 ? 释放时间片,上下文切换 加载上下文:flag=true + //Thread.yield(); + //能够跳出循环 内存屏障 + //System.out.println(count); + + //LockSupport.unpark(Thread.currentThread()); + + //shortWait(1000000); //1ms + //shortWait(1000); +// long start = System.nanoTime(); +// long end = 0; +// // do while while? +// while (start + 1000000 >= end) { +// end = System.nanoTime(); +// } + +// try { +// Thread.sleep(1); //内存屏障 +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } + + //总结: Java中可见性如何保证? 方式归类有两种: + //1. jvm层面 storeLoad内存屏障 ===> x86 lock替代了mfence + // 2. 上下文切换 Thread.yield(); + + // java + // volatile 锁机制 + //当前线程对共享变量的操作会存在读不到,或者不能立即读到另一个线程对此变量的写操作 + + // lock 硬件层面扩展 JMM为什么选择共享内存模型 + + } + System.out.println(Thread.currentThread().getName() + "跳出循环: count=" + count); + } + + public static void main(String[] args) throws InterruptedException { + VisibilityTest test = new VisibilityTest(); + + // 线程threadA模拟数据加载场景 + Thread threadA = new Thread(() -> test.load(), "threadA"); + threadA.start(); + + // 让threadA执行一会儿 + Thread.sleep(1000); + // 线程threadB通过flag控制threadA的执行时间 + Thread threadB = new Thread(() -> test.refresh(), "threadB"); + threadB.start(); + + } + + + public static void shortWait(long interval) { + long start = System.nanoTime(); + long end; + do { + end = System.nanoTime(); + } while (start + interval >= end); + } +} diff --git a/src/main/java/com/tuling/jucdemo/jmm/VolatileTest2.java b/src/main/java/com/tuling/jucdemo/jmm/VolatileTest2.java new file mode 100644 index 00000000..e931c495 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/jmm/VolatileTest2.java @@ -0,0 +1,33 @@ +package com.tuling.jucdemo.jmm; + +public class VolatileTest2 { + + private static volatile boolean flag = true; + + public static void main(String[] args) { + + new Thread(new Runnable() { + @Override + public void run() { + while (true){ + if (flag){ + System.out.println("trun on"); + flag = false; + } + } + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + while (true){ + if (!flag){ + System.out.println("trun off"); + flag = true; + } + } + } + }).start(); + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/lock/CASLock.java b/src/main/java/com/tuling/jucdemo/lock/CASLock.java new file mode 100644 index 00000000..9b0aab8b --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/lock/CASLock.java @@ -0,0 +1,38 @@ +package com.tuling.jucdemo.lock; + +import com.tuling.jucdemo.factory.UnsafeFactory; +import sun.misc.Unsafe; + +/** + * @author Fox + */ +public class CASLock { + + //加锁标记 + private volatile int state; + private static final Unsafe UNSAFE; + private static final long OFFSET; + + static { + try { + UNSAFE = UnsafeFactory.getUnsafe(); + OFFSET = UnsafeFactory.getFieldOffset( + UNSAFE, CASLock.class, "state"); + } catch (Exception e) { + throw new Error(e); + } + } + + public boolean cas() { + return UNSAFE.compareAndSwapInt(this, OFFSET, 0, 1); + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + +} diff --git a/src/main/java/com/tuling/jucdemo/lock/TulingLock.java b/src/main/java/com/tuling/jucdemo/lock/TulingLock.java new file mode 100644 index 00000000..3a0a827e --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/lock/TulingLock.java @@ -0,0 +1,44 @@ +package com.tuling.jucdemo.lock; + +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +/** + * @author Fox + * + */ +public class TulingLock extends AbstractQueuedSynchronizer{ + + @Override + protected boolean tryAcquire(int unused) { + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + + @Override + protected boolean tryRelease(int unused) { + setExclusiveOwnerThread(null); + setState(0); + return true; + } + + public void lock() { + acquire(1); + } + + public boolean tryLock() { + return tryAcquire(1); + } + + public void unlock() { + release(1); + } + + public boolean isLocked() { + return isHeldExclusively(); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/sync/SyncWaitTest.java b/src/main/java/com/tuling/jucdemo/sync/SyncWaitTest.java new file mode 100644 index 00000000..69af22df --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/sync/SyncWaitTest.java @@ -0,0 +1,46 @@ +package com.tuling.jucdemo.sync; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + */ +@Slf4j +public class SyncWaitTest { + + private Object lock = new Object(); + + public void test() { + log.debug(Thread.currentThread().getName()+" start"); + synchronized (lock){ + log.debug(Thread.currentThread().getName()+" execute"); + try { + //Thread.sleep(5000); + lock.wait(5000); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.debug(Thread.currentThread().getName()+" end"); + } + + } + + + + public static void main(String[] args) { + SyncWaitTest test = new SyncWaitTest(); + + for(int i=0;i<2;i++){ + new Thread(new Runnable() { + @Override + public void run() { + test.test(); + } + },"thread"+i).start(); + } + + } + + +} diff --git a/src/main/java/com/tuling/jucdemo/threadactiveness/Chopstick.java b/src/main/java/com/tuling/jucdemo/threadactiveness/Chopstick.java new file mode 100644 index 00000000..1a472f18 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadactiveness/Chopstick.java @@ -0,0 +1,20 @@ +package com.tuling.jucdemo.threadactiveness; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @author Fox + * 筷子 + */ +@Data +@AllArgsConstructor +public class Chopstick { + int number; + + @Override + public String toString() { + return "筷子{" + number + '}'; + } +} + diff --git a/src/main/java/com/tuling/jucdemo/threadactiveness/DeadLockTest.java b/src/main/java/com/tuling/jucdemo/threadactiveness/DeadLockTest.java new file mode 100644 index 00000000..40cc8c54 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadactiveness/DeadLockTest.java @@ -0,0 +1,44 @@ +package com.tuling.jucdemo.threadactiveness; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 死锁 + */ +@Slf4j +public class DeadLockTest { + + private static String a = "a"; + private static String b = "b"; + + public static void main(String[] args) { + Thread threadA = new Thread(()->{ + synchronized (a) { + log.debug("threadA进入a同步块,执行中..."); + try { + Thread.sleep(2000); + synchronized (b) { + log.debug("threadA进入b同步块,执行中..."); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + },"threadA"); + + Thread threadB = new Thread(()->{ + synchronized (b) { + log.debug("threadB进入b同步块,执行中..."); + synchronized (a) { + log.debug("threadB进入a同步块,执行中..."); + } + } + },"threadB"); + + threadA.start(); + threadB.start(); + + } + +} diff --git a/src/main/java/com/tuling/jucdemo/threadactiveness/HungryTest.java b/src/main/java/com/tuling/jucdemo/threadactiveness/HungryTest.java new file mode 100644 index 00000000..73f0abc8 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadactiveness/HungryTest.java @@ -0,0 +1,76 @@ +package com.tuling.jucdemo.threadactiveness; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import lombok.extern.slf4j.Slf4j; + + +/** + * @author Fox + * 定长线程池饥饿示例 + */ +@Slf4j +public class HungryTest { + + static final List FOODS = Arrays.asList("猪脚饭", "宫保鸡丁", "鱼香肉丝", "麻婆豆腐"); + + static final Random RANDOM = new Random(); + + static ExecutorService pool = Executors.newFixedThreadPool(2); + + //随机做菜 + public static String cooking() { + return FOODS.get(RANDOM.nextInt(FOODS.size())); + } + + + public static void main(String[] args) throws InterruptedException { + // 服务员需要点菜、以及自己去做菜 + HungryTest.test(); + } + + public static void test() { + pool.execute(() -> { + //服务员开始点菜 + log.info("开始给顾客点菜"); + Future food = pool.submit(() -> { + log.info("开始做菜"); + return cooking(); + }); + + //该服务员点完菜上菜 + try { + log.info("上菜:{}", food.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + }); + + pool.execute(() -> { + //服务员开始点菜 + log.info("开始给顾客点菜"); + Future food = pool.submit(() -> { + log.info("开始做菜"); + return cooking(); + }); + + //该服务员点完菜上菜 + try { + log.info("上菜:{}", food.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + }); + + } +} diff --git a/src/main/java/com/tuling/jucdemo/threadactiveness/LiveLockTest.java b/src/main/java/com/tuling/jucdemo/threadactiveness/LiveLockTest.java new file mode 100644 index 00000000..4b37f4c9 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadactiveness/LiveLockTest.java @@ -0,0 +1,113 @@ +package com.tuling.jucdemo.threadactiveness; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 活锁 + */ +@Slf4j +public class LiveLockTest { + + /** + * 定义一个勺子,ower 表示这个勺子的拥有者 + */ + static class Spoon { + Diner owner; + + public Spoon(Diner diner) { + this.owner = diner; + } + + public String getOwnerName() { + return owner.getName(); + } + + public void setOwner(Diner diner) { + this.owner = diner; + } + + //表示正在用餐 + public void use() { + log.info( "{} 用这个勺子吃饭.",owner.getName()); + } + } + + /** + * 定义一个晚餐类 + */ + static class Diner { + + private boolean isHungry; + //用餐者的名字 + private String name; + + public Diner(boolean isHungry, String name) { + this.isHungry = isHungry; + this.name = name; + } + + //和某人吃饭 + public void eatWith(Diner diner, Spoon sharedSpoon) { + try { + synchronized (sharedSpoon) { + while (isHungry) { + //当前用餐者和勺子拥有者不是同一个人,则进行等待 + while (!sharedSpoon.getOwnerName().equals(name)) { + sharedSpoon.wait(); + } + if (diner.isHungry()) { + log.info( "{}:亲爱的我饿了,然后{}把勺子给了{}", + diner.getName(),name,diner.getName()); + sharedSpoon.setOwner(diner); + //唤醒等待的线程 + sharedSpoon.notifyAll(); + } else { + //用餐 + sharedSpoon.use(); + sharedSpoon.setOwner(diner); + isHungry = false; + } + Thread.sleep(500); + } + } + } catch (InterruptedException e) { + log.info("{} is interrupted.",name); + } + } + + public boolean isHungry() { + return isHungry; + } + + public String getName() { + return name; + } + + } + + public static void main(String[] args) { + final Diner husband = new Diner(true, "丈夫"); + final Diner wife = new Diner(true, "妻子"); + //最开始牛郎持有勺子 + final Spoon sharedSpoon = new Spoon(husband); + + //织女和牛郎吃饭 + Thread h = new Thread(()->wife.eatWith(husband, sharedSpoon)); + h.start(); + + //牛郎和织女吃饭 + Thread w = new Thread(()->husband.eatWith(wife, sharedSpoon)); + w.start(); + + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + h.interrupt(); + w.interrupt(); + + } + +} diff --git a/src/main/java/com/tuling/jucdemo/threadactiveness/Philosopher.java b/src/main/java/com/tuling/jucdemo/threadactiveness/Philosopher.java new file mode 100644 index 00000000..ee385fbe --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadactiveness/Philosopher.java @@ -0,0 +1,65 @@ +package com.tuling.jucdemo.threadactiveness; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 哲学家 + */ +@Slf4j +public class Philosopher extends Thread { + + private Chopstick left; + private Chopstick right; + + public Philosopher(String name, Chopstick left, Chopstick right) { + super(name); + this.left = left; + this.right = right; + } + + public void eat() { + log.debug("eating..."); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void think() { + log.debug("thinking..."); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override + public void run() { + while (true) { + // 获得左手筷子 + synchronized (left) { + log.debug("获得左手筷子" + left.getNumber()); +// try { +// left.wait(10); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } + // 获得右手筷子 + synchronized (right) { + log.debug("获得右手筷子" + right.getNumber()); + // 吃饭 + eat(); + //left.notifyAll(); + } + // 放下右手筷子 + } + // 放下左手筷子 + log.debug("吃完了,把筷子放回了原处,开始thinking"); + think(); + } + } + +} diff --git a/src/main/java/com/tuling/jucdemo/threadactiveness/PhilosopherEatTest.java b/src/main/java/com/tuling/jucdemo/threadactiveness/PhilosopherEatTest.java new file mode 100644 index 00000000..e30dbe72 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadactiveness/PhilosopherEatTest.java @@ -0,0 +1,23 @@ +package com.tuling.jucdemo.threadactiveness; + +/** + * @author Fox + * 哲学家就餐 + */ +public class PhilosopherEatTest { + + public static void main(String[] args) { + + Chopstick c1 = new Chopstick(1); + Chopstick c2 = new Chopstick(2); + Chopstick c3 = new Chopstick(3); + Chopstick c4 = new Chopstick(4); + Chopstick c5 = new Chopstick(5); + new Philosopher("苏格拉底", c1, c2).start(); + new Philosopher("柏拉图", c2, c3).start(); + new Philosopher("亚里士多德", c3, c4).start(); + new Philosopher("赫拉克利特", c4, c5).start(); + new Philosopher("阿基米德", c5, c1).start(); + + } +} diff --git a/src/main/java/com/tuling/jucdemo/threadbase/LockSupportTest.java b/src/main/java/com/tuling/jucdemo/threadbase/LockSupportTest.java new file mode 100644 index 00000000..8c6e7398 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/LockSupportTest.java @@ -0,0 +1,26 @@ +package com.tuling.jucdemo.threadbase; + +import java.util.concurrent.locks.LockSupport; + +public class LockSupportTest { + + public static void main(String[] args) { + Thread parkThread = new Thread(new ParkThread()); + parkThread.start(); + + System.out.println("唤醒parkThread"); + //为指定线程parkThread提供“许可” + LockSupport.unpark(parkThread); + } + + static class ParkThread implements Runnable{ + + @Override + public void run() { + System.out.println("ParkThread开始执行"); + // 等待“许可” + LockSupport.park(); + System.out.println("ParkThread执行完成"); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/threadbase/ParkUnparkDemo.java b/src/main/java/com/tuling/jucdemo/threadbase/ParkUnparkDemo.java new file mode 100644 index 00000000..8e1a6bdc --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/ParkUnparkDemo.java @@ -0,0 +1,99 @@ +package com.tuling.jucdemo.threadbase; + +import java.util.concurrent.locks.LockSupport; + +public class ParkUnparkDemo { + //包子铺对象 + volatile Object bozipu = null; + //资源锁 + Object baozi_lock = new Object(); + + public static void main(String[] args) throws Exception{ + System.out.println("主线程开始运行"); + //new ParkUnparkDemo().parkUnparkTest(); + new ParkUnparkDemo().parkUnparkExceptionTest(); + //new ParkUnparkDemo().moreUnparkTest(); + //new ParkUnparkDemo().moreParkTest(); + + + } + + /** + * 测试park/unpark方法的使用 + */ + public void parkUnparkTest() throws Exception { + //开启消费者线程1:等待包子铺有包子之后,进行消费买包子 + Thread consumer =new Thread(() -> { + //如果包子铺没有开业,则等待包子铺开业的"许可" + System.out.println("等待包子铺开张。。。"); + //这里使用while进行是否被唤醒,不要使用if,因为会有伪唤醒的状态 + while (bozipu == null){ + LockSupport.park(); + System.out.println("包子已经买到,可以回家了!"); + } + }); + consumer.start(); + + //等待3秒钟开始创建包子铺 + Thread.sleep(3000); + bozipu = new Object(); + //给线程consummer颁发许可 + LockSupport.unpark(consumer); + System.out.println("已经通知消费者包子铺开张"); + } + + /** + * park/unpark方法异常情况测试 + */ + public void parkUnparkExceptionTest() throws Exception{ + //开启消费者线程1:等待包子铺有包子之后,进行消费买包子 + Thread consumer =new Thread(() -> { + //如果包子铺没有开业,则等待包子铺开业的"许可" + System.out.println("等待包子铺开张。。。"); + if(bozipu == null){ + //拿到baozi_lock锁 + synchronized (baozi_lock) { + LockSupport.park(); + System.out.println("包子已经买到,可以回家了!"); + } + } + }); + consumer.start(); + + //等待3秒钟开始创建包子铺 + Thread.sleep(3000); + bozipu = new Object(); + //此时因为baozi_lock锁已经被消费者占有,无法继续执行 + synchronized (baozi_lock){ + //给线程consummer颁发许可 + LockSupport.unpark(consumer); + System.out.println("已经通知消费者包子铺开张"); + } + } + + /** + * 多次调用unpark方法,调用一次park方法,线程会继续运行 + */ + public void moreUnparkTest(){ + LockSupport.unpark(Thread.currentThread()); + LockSupport.unpark(Thread.currentThread()); + LockSupport.unpark(Thread.currentThread()); + System.out.println("调用了三次unpark"); + LockSupport.park(Thread.currentThread()); + System.out.println("调用了一次park"); + } + + /** + * 多次调用park方法,调用一次unpark方法,线程会进入等待状态 + */ + public void moreParkTest(){ + LockSupport.park(Thread.currentThread()); + System.out.println("调用了一次park"); + + LockSupport.park(Thread.currentThread()); + LockSupport.park(Thread.currentThread()); + System.out.println("又调用了两次park"); + LockSupport.unpark(Thread.currentThread()); + System.out.println("调用了一次unpark方法"); + } +} diff --git a/src/main/java/com/tuling/jucdemo/threadbase/PipedTest.java b/src/main/java/com/tuling/jucdemo/threadbase/PipedTest.java new file mode 100644 index 00000000..054f70f5 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/PipedTest.java @@ -0,0 +1,45 @@ +package com.tuling.jucdemo.threadbase; + +import java.io.IOException; +import java.io.PipedReader; +import java.io.PipedWriter; + +public class PipedTest { + public static void main(String[] args) throws Exception { + PipedWriter out = new PipedWriter(); + PipedReader in = new PipedReader(); + // 将输出流和输入流进行连接,否则在使用时会抛出IOException + out.connect(in); + + Thread printThread = new Thread(new Print(in), "PrintThread"); + printThread.start(); + + int receive = 0; + try { + while ((receive = System.in.read()) != -1) { + out.write(receive); + } + } finally { + out.close(); + } + } + + static class Print implements Runnable { + private PipedReader in; + + public Print(PipedReader in) { + this.in = in; + } + + @Override + public void run() { + int receive = 0; + try { + while ((receive = in.read()) != -1) { + System.out.print((char) receive); + } + } catch (IOException ex) { + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/threadbase/SellTicketDemo.java b/src/main/java/com/tuling/jucdemo/threadbase/SellTicketDemo.java new file mode 100644 index 00000000..7449b68f --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/SellTicketDemo.java @@ -0,0 +1,54 @@ +package com.tuling.jucdemo.threadbase; + +/** + * @author Fox + * 一个简单卖票程序:多个窗口卖票 + */ +public class SellTicketDemo implements Runnable { + /** + * 车票 + */ + private int ticket; + + public SellTicketDemo() { + this.ticket = 1000; + } + + @Override + public void run() { + while (ticket > 0) { + synchronized (this) { + if (ticket > 0) { + try { + // 线程进入暂时的休眠 + Thread.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // 获取到当前正在执行的程序的名称,打印余票 + System.out.println(Thread.currentThread().getName() + + ":正在执行操作,余票:" + ticket--); + } + } + Thread.yield(); + } + } + + public static void main(String[] args) { + SellTicketDemo demo = new SellTicketDemo(); + + Thread thread1 = new Thread(demo,"thread1"); + Thread thread2 = new Thread(demo,"thread2"); + Thread thread3 = new Thread(demo,"thread3"); + Thread thread4 = new Thread(demo,"thread4"); + //priority优先级默认是5,最低1,最高10 + thread1.setPriority(Thread.MIN_PRIORITY); + thread2.setPriority(Thread.MAX_PRIORITY); + thread3.setPriority(Thread.MIN_PRIORITY); + thread4.setPriority(Thread.MAX_PRIORITY); + thread1.start(); + thread2.start(); + thread3.start(); + thread4.start(); + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/threadbase/ThreadExecuteTest.java b/src/main/java/com/tuling/jucdemo/threadbase/ThreadExecuteTest.java new file mode 100644 index 00000000..73155faa --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/ThreadExecuteTest.java @@ -0,0 +1,88 @@ +package com.tuling.jucdemo.threadbase; + +import java.util.Random; +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; +import java.util.concurrent.FutureTask; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + */ +@Slf4j +public class ThreadExecuteTest { + + public static void main(String[] args) throws ExecutionException, InterruptedException { + + Runnable runnable = new Runnable() { + @Override + public void run() { + log.debug("通过Runnable方式执行任务"); + } + }; + + // 操作系统创建线程 + // java Thread --> jvm JavaThread---->os Thread + + // new Thread(runnable).start(); + // new Object()--->jvm JavaThread + + new Thread(runnable).start(); + // 这是一个真正的线程吗? 普通对象的方法调用 + new Thread(runnable).run(); + runnable.run(); + + +// FutureTask task = new FutureTask(new Callable() { +// @Override +// public Object call() throws Exception { +// log.debug("通过Callable方式执行任务"); +// Thread.sleep(3000); +// return "返回任务结果"; +// } +// }); +// +// new Thread(task).start(); +// log.debug("结果:{}",task.get()); + + +// ExecutorService executor = Executors.newFixedThreadPool(2); +// +// log.debug("monkey下班回家做饭"); +// Future future = executor.submit(new Callable() { +// @Override +// public String call() { +// //真正的任务在这里执行,这里的返回值类型为String,可以为任意类型 +// log.debug("开始煮饭"); +// try { +// Thread.sleep(5000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// return "饭熟了"; +// } +// }); +// Future future2 = executor.submit(new Callable() { +// @Override +// public String call() { +// //真正的任务在这里执行,这里的返回值类型为String,可以为任意类型 +// log.debug("开始做菜"); +// try { +// Thread.sleep(3000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// return "菜好了"; +// } +// }); +// +// log.debug("{},{},monkey开始吃饭",future.get(), future2.get()); +// +// executor.shutdown(); + + } +} diff --git a/src/main/java/com/tuling/jucdemo/threadbase/ThreadInterruptTest.java b/src/main/java/com/tuling/jucdemo/threadbase/ThreadInterruptTest.java new file mode 100644 index 00000000..2b4de77d --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/ThreadInterruptTest.java @@ -0,0 +1,45 @@ +package com.tuling.jucdemo.threadbase; + +import java.util.concurrent.locks.LockSupport; + +/** + * @author Fox + * 中断机制 + */ +public class ThreadInterruptTest { + + static int i = 0; + + public static void main(String[] args) { + System.out.println("begin"); + Thread t1 = new Thread(new Runnable() { + @Override + public void run() { + while (true) { + i++; + System.out.println(i); + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //Thread.interrupted() 清除中断标志位 + //Thread.currentThread().isInterrupted() 不会清除中断标志位 + if (Thread.interrupted() ) { + System.out.println("========="); + } + if(i==10){ + break; + } + + } + } + }); + + t1.start(); + //不会停止线程t1,只会设置一个中断标志位 flag=true + t1.interrupt(); + + } +} diff --git a/src/main/java/com/tuling/jucdemo/threadbase/ThreadJoinDemo.java b/src/main/java/com/tuling/jucdemo/threadbase/ThreadJoinDemo.java new file mode 100644 index 00000000..94a11b8d --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/ThreadJoinDemo.java @@ -0,0 +1,27 @@ +package com.tuling.jucdemo.threadbase; + +public class ThreadJoinDemo { + + public static void main(String[] sure) throws InterruptedException { + + Thread t = new Thread(new Runnable() { + @Override + public void run() { + System.out.println("t begin"); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("t finished"); + } + }); + long start = System.currentTimeMillis(); + t.start(); + //主线程等待线程t执行完成 + t.join(); + + System.out.println("执行时间:" + (System.currentTimeMillis() - start)); + System.out.println("Main finished"); + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/threadbase/ThreadStateTest.java b/src/main/java/com/tuling/jucdemo/threadbase/ThreadStateTest.java new file mode 100644 index 00000000..11a5ee87 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/ThreadStateTest.java @@ -0,0 +1,28 @@ +package com.tuling.jucdemo.threadbase; + +import java.util.concurrent.locks.LockSupport; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + */ +@Slf4j +public class ThreadStateTest { + + public static void main(String[] args) throws InterruptedException { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + LockSupport.park(); + } + }); + log.debug("线程状态:{}", thread.getState()); + thread.start(); + log.debug("线程状态:{}", thread.getState()); + Thread.sleep(100); + log.debug("线程状态:{}", thread.getState()); + + + } +} diff --git a/src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo.java b/src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo.java new file mode 100644 index 00000000..a6aa8ce0 --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo.java @@ -0,0 +1,42 @@ +package com.tuling.jucdemo.threadbase; + +/** + * @author Fox + */ +public class ThreadStopDemo { + + private static Object lock = new Object(); + + public static void main(String[] args) throws InterruptedException { + + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + synchronized (lock) { + System.out.println(Thread.currentThread().getName() + "获取锁"); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println(Thread.currentThread().getName() + "执行完成"); + } + }); + thread.start(); + Thread.sleep(2000); + // 停止thread,并释放锁 + thread.stop(); + + new Thread(new Runnable() { + @Override + public void run() { + System.out.println(Thread.currentThread().getName() + "等待获取锁"); + synchronized (lock) { + System.out.println(Thread.currentThread().getName() + "获取锁"); + } + } + }).start(); + + } +} diff --git a/src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo2.java b/src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo2.java new file mode 100644 index 00000000..bbb2d5fa --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/ThreadStopDemo2.java @@ -0,0 +1,32 @@ +package com.tuling.jucdemo.threadbase; + +/** + * @author Fox + */ +public class ThreadStopDemo2 implements Runnable { + + @Override + public void run() { + int count = 0; + while (!Thread.currentThread().isInterrupted() && count < 1000) { + System.out.println("count = " + count++); + + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + //重新设置线程中断状态为true + Thread.currentThread().interrupt(); + } + } + System.out.println("线程停止: stop thread"); + } + + public static void main(String[] args) throws InterruptedException { + Thread thread = new Thread(new ThreadStopDemo2()); + thread.start(); + Thread.sleep(5); + thread.interrupt(); + } +} + diff --git a/src/main/java/com/tuling/jucdemo/threadbase/VolatileDemo.java b/src/main/java/com/tuling/jucdemo/threadbase/VolatileDemo.java new file mode 100644 index 00000000..bb75498f --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/VolatileDemo.java @@ -0,0 +1,33 @@ +package com.tuling.jucdemo.threadbase; + +public class VolatileDemo { + + private static volatile boolean flag = true; + + public static void main(String[] args) { + + new Thread(new Runnable() { + @Override + public void run() { + while (true){ + if (flag){ + System.out.println("trun on"); + flag = false; + } + } + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + while (true){ + if (!flag){ + System.out.println("trun off"); + flag = true; + } + } + } + }).start(); + } +} \ No newline at end of file diff --git a/src/main/java/com/tuling/jucdemo/threadbase/WaitDemo.java b/src/main/java/com/tuling/jucdemo/threadbase/WaitDemo.java new file mode 100644 index 00000000..d9e33a8f --- /dev/null +++ b/src/main/java/com/tuling/jucdemo/threadbase/WaitDemo.java @@ -0,0 +1,51 @@ +package com.tuling.jucdemo.threadbase; + +public class WaitDemo { + + private static Object lock = new Object(); + private static boolean flag = true; + + public static void main(String[] args) { + new Thread(new Runnable() { + @Override + public void run() { + synchronized (lock){ + while (flag){ + try { + System.out.println("wait start ......."); + //等待 + lock.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + System.out.println("wait end ....... "); + } + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + if (flag){ + synchronized (lock){ + if (flag){ + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //通知 + lock.notifyAll(); + System.out.println("notify ......."); + flag = false; + } + + } + } + } + }).start(); + } +} \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/ListNodeRevseve.java b/src/main/java/org/cc/leetcode/ListNodeRevseve.java new file mode 100644 index 00000000..175fac80 --- /dev/null +++ b/src/main/java/org/cc/leetcode/ListNodeRevseve.java @@ -0,0 +1,68 @@ +package org.cc.leetcode; + +import com.google.gson.Gson; +import org.cc.leetcode.util.ListNode; + +import java.util.Stack; + +/** + * @ClassName : ListNodeRevseve + * + * @Description : 链表反转 + * @param: + * @Author : CC + * @Date: 2023-05-05 22:00 + */ +public class ListNodeRevseve { + + + public static void main(String[] args) { + ListNodeRevseve lnr=new ListNodeRevseve(); + int[] tar1={ 1,2,3,0,-2,-1,1,2}; + ListNode l1= ListNode.initListNode(tar1); + //使用栈来做处理 + ListNode res=lnr.resevebyStack(l1); + ListNode.printListNode(res); + System.out.println("************"); + res=lnr.reseveListNode(ListNode.initListNode(tar1)); + ListNode.printListNode(res); + +// System.out.println("res "+gson.toJson(res)); + } + + /*** + * + * 使用栈来做处理 + * */ + private ListNode resevebyStack(ListNode node){ + Stack stack =new Stack<>(); + while (node!=null){ + stack.push(node); + node=node.next; + } + ListNode n=new ListNode(0); + ListNode res=n; + while (!stack.empty()){ + n.next=stack.pop(); + n=n.next; + } + n.next=null; + return res.next; + } + + + //指针反转 1-》2——》3 + //编程 1<-2->3 + private ListNode reseveListNode(ListNode n){ + ListNode head=n; + ListNode temp=null; + while (head!=null){ + ListNode node=new ListNode(head.val); + node.next=temp; + temp=node;// + head=head.next; + } + return temp; + } + +} \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/TwoSplite.java b/src/main/java/org/cc/leetcode/TwoSplite.java new file mode 100644 index 00000000..11c33c30 --- /dev/null +++ b/src/main/java/org/cc/leetcode/TwoSplite.java @@ -0,0 +1,64 @@ +package org.cc.leetcode; + +/** + * @ClassName : TwoSplite + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-27 09:12 + */ +public class TwoSplite { + public static void main(String[] args) { +// int[] arr=new int[]{ -1,0,3,5,9,12}; 9 +// int[] arr=new int[]{ -1,0,3,5,9,12};//2 + int[] arr=new int[]{ 5};//5 + TwoSplite ts=new TwoSplite(); + System.out.println(ts.splite(arr,5)); +// System.out.println(ts.search(arr,9)); + } + /*** + * array 有序数组 + * target要找到的数字 + * */ + private int splite(int[] array,int target){ + if(array==null||array.length==0){ + return -1; + }else { + int left=0; + int right=array.length-1; + while (left<=right){//=是解决单个的问题 + System.out.println(left+" "+right); + int mid=(right-left)/2+left; + if(array[mid]==target){ + return mid; + }else if(array[mid]=nums.length){ + return true; + }else { + i=nums[i]+i; + } + } + + } + return false; + } +} + + diff --git a/src/main/java/org/cc/leetcode/onehundred/Num56.java b/src/main/java/org/cc/leetcode/onehundred/Num56.java new file mode 100644 index 00000000..93ff1ec9 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/Num56.java @@ -0,0 +1,148 @@ +package org.cc.leetcode.onehundred; + +import com.google.gson.Gson; +import org.apache.commons.lang.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/**** + 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 + + 示例 1: + + 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] + 输出:[[1,6],[8,10],[15,18]] + 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. + 示例 2: + + 输入:intervals = [[1,4],[4,5]] + 输出:[[1,5]] + 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。 + + + 提示: + + 1 <= intervals.length <= 104 + intervals[i].length == 2 + 0 <= starti <= endi <= 104 + * */ +/** + * https://leetcode.cn/problems/merge-intervals/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num56 { + public static void main(String[] args) { + Num56 test=new Num56(); +// ListNode.printListNode(); +// int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; + + //[[1,3],[2,6],[8,10],[15,18]] + int[][] tar=test.init(); + + int[][] res=test.merge(tar); + Gson g=new Gson(); + System.out.println("res "+g.toJson(res)); + + } + + private int[][] init(){ +// int[] a1=new int[]{1,3}; +// int[] a2=new int[]{2,6}; +// int[] a3=new int[]{8,10}; +// int[] a4=new int[]{15,18}; +// int[][] res=new int[][]{a1,a2,a3,a4}; + + +// int[] a1=new int[]{1,4}; +// int[] a2=new int[]{4,5}; +// int[][] res=new int[][]{a1,a2}; + + int[] a1=new int[]{1,4}; + int[] a2=new int[]{0,2}; + int[] a3=new int[]{3,5}; + int[][] res=new int[][]{a1,a2,a3}; + return res; + } + + //转换list为数组,以复合要求 + private int[][] convertList2Arr( List l){ + if(l==null||l.size()==0){ + return null; + }else { + int[][] res=new int[l.size()][]; + for (int i = 0; i slen){//循环少的数组 + for (int i =fir[0]; i =sec[0]&&i<=sec[1]){//存在交集 + return true; + } + } + }else { + for (int i =sec[0]; i =fir[0]&&i<=fir[1]){//存在交集 + return true; + } + } + } + return false; + } + public int[][] merge(int[][] intervals) { + List list=new ArrayList<>(); + Arrays.sort(intervals, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[0]-o2[0]; + } + }); + if(intervals!=null&&intervals.length==1){//只有一个不用排序直接返回 + list.add(intervals[0]); + return convertList2Arr(list) ; + } + for (int i = 0; i secondArr[1]?firstArr[1]:secondArr[1]; + int[] temp=new int[]{start,end}; + intervals[next]=temp;//更新,方便该节点和后面的合并 + if(list.contains(firstArr)){ + list.remove(firstArr); + } + if(!list.contains(temp))//去除 + list.add(temp); + }else {//无交集,增加 + if(!list.contains(firstArr)) + list.add(firstArr); + if(!list.contains(secondArr)) + list.add(secondArr); + } + + }else { + + } + + } + return convertList2Arr(list) ; + } +} + + diff --git a/src/main/java/org/cc/leetcode/onehundred/Num57.java b/src/main/java/org/cc/leetcode/onehundred/Num57.java new file mode 100644 index 00000000..19abf17b --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/Num57.java @@ -0,0 +1,187 @@ +package org.cc.leetcode.onehundred; + +import com.google.gson.Gson; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +/**** + 给你一个 无重叠的 ,按照区间起始端点排序的区间列表。 + + 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 + + + 示例 1: + + 输入:intervals = [[1,3],[6,9]], newInterval = [2,5] + 输出:[[1,5],[6,9]] + 示例 2: + + 输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] + 输出:[[1,2],[3,10],[12,16]] + 解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。 + 示例 3: + + 输入:intervals = [], newInterval = [5,7] + 输出:[[5,7]] + 示例 4: + + 输入:intervals = [[1,5]], newInterval = [2,3] + 输出:[[1,5]] + 示例 5: + + 输入:intervals = [[1,5]], newInterval = [2,7] + 输出:[[1,7]] + + + 提示: + + 0 <= intervals.length <= 104 + intervals[i].length == 2 + 0 <= intervals[i][0] <= intervals[i][1] <= 105 + intervals 根据 intervals[i][0] 按 升序 排列 + newInterval.length == 2 + 0 <= newInterval[0] <= newInterval[1] <= 105 +/** + * https://leetcode.cn/problems/insert-interval/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num57 { + public static void main(String[] args) { + Num57 test=new Num57(); +// ListNode.printListNode(); +// int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; + + //[[1,3],[2,6],[8,10],[15,18]] + int[][] tar=test.init(); + int[] src=new int[]{2,5}; + + int[][] res=test.insert(tar,src); + Gson g=new Gson(); + System.out.println("res "+g.toJson(res)); + + } + //转换list为数组,以复合要求 + private int[][] convertList2Arr( List l){ + if(l==null||l.size()==0){ + return null; + }else { + int[][] res=new int[l.size()][]; + for (int i = 0; i slen){//循环少的数组 + for (int i =fir[0]; i =sec[0]&&i<=sec[1]){//存在交集 + return true; + } + } + }else { + for (int i =sec[0]; i =fir[0]&&i<=fir[1]){//存在交集 + return true; + } + } + } + return false; + } + + private int[][] initArray(int[][] intervals, int[] newInterval){ + int[][] resArray=new int[intervals.length+1][]; + for (int i = 0; i < intervals.length ; i++) { + resArray[i]=intervals[i]; + } + resArray[intervals.length]=newInterval; + Arrays.sort(resArray, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[0]-o2[0]; + } + }); + return resArray; + } + + public int[][] insert(int[][] intervals, int[] newInterval) { + List list=new ArrayList<>(); + if(intervals!=null&&intervals.length==0){//只有一个不用排序直接返回 + return new int[][]{newInterval}; + } + if(!isContain(intervals,newInterval)){ + //如果目标不在各个数组的交集中,直接增加,然后排序返回 + return initArray(intervals,newInterval); + }else { + int[][] arrays=initArray(intervals, newInterval); + for (int i = 0; i fir[1]?sec[1] :fir[1]; + int[] temp=new int[]{start,end}; + arrays[next]=temp; + if(list.contains(fir))//合并,去除第一个 + list.remove(fir); + if(!list.contains(temp)) + list.add(temp); + + }else { + if(!list.contains(fir)){ + list.add(fir); + } + if(!list.contains(sec)){ + list.add(sec); + } + } + } + } + return convertList2Arr(list); + } + + } +} + + diff --git a/src/main/java/org/cc/leetcode/onehundred/thirsty/Num21.java b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num21.java new file mode 100644 index 00000000..b0a4d18c --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num21.java @@ -0,0 +1,63 @@ +package org.cc.leetcode.onehundred.thirsty; + +import com.google.gson.Gson; +import org.cc.leetcode.util.ListNode; + +/** + * https://leetcode.cn/problems/merge-two-sorted-lists/ + * @ClassName : Num21 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num21 { + public static void main(String[] args) { + Num21 test=new Num21(); +// ListNode.printListNode(); +// int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; + + int[] tar1={ 3,0,-2,-1,1,2}; + int[] tar2={ 1,5,5,8}; + ListNode res=test.mergeTwoLists(ListNode.initListNode(tar1),ListNode.initListNode(tar2)); + Gson gson=new Gson(); + System.out.println("res "+gson.toJson(res)); + } + + public ListNode mergeTwoLists(ListNode n1, ListNode n2) { + + ListNode n=new ListNode(0); + ListNode root=n; + while (n1!=null&&n2!=null){ + if(n1.val>=n2.val){ + n.next=n2; + n2=n2.next; + }else { + n.next=n1; + n1=n1.next; + } + n=n.next; + } + n.next=n1==null?n2:n1; + return root.next; + } + +} + + + +/**** + * + * 输入:l1 = [1,2,4], l2 = [1,3,4] + * 输出:[1,1,2,3,4,4] + * 示例 2: + * + * 输入:l1 = [], l2 = [] + * 输出:[] + * 示例 3: + * + * 输入:l1 = [], l2 = [0] + * 输出:[0] + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/thirsty/Num23.java b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num23.java new file mode 100644 index 00000000..0ce4bc18 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num23.java @@ -0,0 +1,106 @@ +package org.cc.leetcode.onehundred.thirsty; + +import com.google.gson.Gson; +import org.cc.leetcode.util.ListNode; + +/** + * https://leetcode.cn/problems/merge-k-sorted-lists/description/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num23 { + public static void main(String[] args) { + Num23 test=new Num23(); +// ListNode.printListNode(); + + + ListNode res=test.mergeKLists(test.init2()); +// ListNode res=test.mergeKLists(test.init1()); + Gson gson=new Gson(); + System.out.println("res "+gson.toJson(res)); + } + private ListNode[] init1(){ + int[] tar2={-1,0,1,2,-1,-4}; + int[] tar3={3,-2,1,0}; + int[] tar1={ 3,0,-2,-1,1,2}; + ListNode l1= ListNode.initListNode(tar1); + ListNode l2= ListNode.initListNode(tar2); + ListNode l3= ListNode.initListNode(tar3); + ListNode[] nodes=new ListNode[]{l1,l2,l3}; + return nodes; + } + + private ListNode[] init2(){ + int[] tar2={1}; + int[] tar3={ 2}; + ListNode l2= ListNode.initListNode(tar2); + ListNode l3= ListNode.initListNode(tar3); + ListNode[] nodes=new ListNode[3]; + nodes[0]=l2; + nodes[2]=l3; + + return nodes; + } + public ListNode mergeKLists(ListNode[] lists) { + ListNode node=null; + for (int i = 0; i < lists.length; i++) { + node=merge2(node,lists[i]); + } + return node; + } + + public ListNode merge2(ListNode n1,ListNode n2) { + + ListNode n=new ListNode(0); + ListNode root=n; + while (n1!=null&&n2!=null){ + if(n1.val>=n2.val){ + n.next=n2; + n2=n2.next; + }else { + n.next=n1; + n1=n1.next; + } + n=n.next; + + } + n.next= n1==null?n2:n1;//加剩下的 + return root.next; + + } +} + + + +/**** + * 给你一个链表数组,每个链表都已经按升序排列。 + * + * 请你将所有链表合并到一个升序链表中,返回合并后的链表。 + * + * + * + * 示例 1: + * + * 输入:lists = [[1,4,5],[1,3,4],[2,6]] + * 输出:[1,1,2,3,4,4,5,6] + * 解释:链表数组如下: + * [ + * 1->4->5, + * 1->3->4, + * 2->6 + * ] + * 将它们合并到一个有序链表中得到。 + * 1->1->2->3->4->4->5->6 + * 示例 2: + * + * 输入:lists = [] + * 输出:[] + * 示例 3: + * + * 输入:lists = [[]] + * 输出:[] + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/thirsty/Num24.java b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num24.java new file mode 100644 index 00000000..d2d74787 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num24.java @@ -0,0 +1,86 @@ +package org.cc.leetcode.onehundred.thirsty; + +import com.google.gson.Gson; +import org.cc.leetcode.util.ListNode; + +import java.util.List; +import java.util.Stack; + +/** + * https://leetcode.cn/problems/swap-nodes-in-pairs/ + * @ClassName : Num21 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num24 { + public static void main(String[] args) { + Num24 test=new Num24(); +// ListNode.printListNode(); +// int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; + + int[] tar1={ 3,0,-2,-1,17}; + ListNode res=test.swapPairs(ListNode.initListNode(tar1) ); + Gson gson=new Gson(); + System.out.println("swapPairs "+gson.toJson(res)); + } + + public ListNode swapPairs(ListNode head) { +// Gson gson=new Gson(); + if(head==null){ + return null; + }else { + Stack stack=new Stack<>(); + ListNode node=new ListNode(0); + ListNode ptr=node; + int i=0; + while (head!=null){ +// System.out.println("res "+gson.toJson(ptr)+"i:"+i+" stack size:"+stack.size()); + if(i!=0&&i%2==0){//需要反转 + node=covert(stack,node); + } + stack.push(head.val); + head=head.next; + i++; + } + if(!stack.empty()){ + node=covert(stack,node); + } + return ptr.next; + } + + } + private ListNode covert(Stack stack,ListNode tar){ +// System.out.println("*****************"); Gson gson=new Gson(); + ListNode n=null; + while (!stack.empty()){ + int num=stack.pop(); +// System.out.println("pop num:"+num); +// System.out.println("tar "+gson.toJson(tar)); + n=new ListNode(num); + tar.next=n; + tar=tar.next; + } + return tar; + } + +} + + + +/**** + * + 输入:head = [1,2,3,4] + 输出:[2,1,4,3] + 示例 2: + + 输入:head = [] + 输出:[] + 示例 3: + + 输入:head = [1] + 输出:[1] + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/thirsty/Num25.java b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num25.java new file mode 100644 index 00000000..c510ac5f --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/thirsty/Num25.java @@ -0,0 +1,189 @@ +package org.cc.leetcode.onehundred.thirsty; + +import com.google.gson.Gson; +import org.cc.leetcode.util.ListNode; + +import java.util.*; + +/** + * https://leetcode.cn/problems/reverse-nodes-in-k-group/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num25 { + public static void main(String[] args) { + Num25 test=new Num25(); +// ListNode.printListNode(); + +// int[] tar1={ 3,0}; + int[] tar1={ 3,0,-2,-1,9,4,5,6,7,8}; + ListNode l1= ListNode.initListNode(tar1); + ListNode.printListNode(l1); + ListNode res=test.reverseKGroup(l1,2); + + Gson gson=new Gson(); + ListNode.printListNode(res); + + res=test.reverseKGroup2(ListNode.initListNode(tar1),2); + ListNode.printListNode(res); + } + + +// 链表中的节点数目为 n +// 1 <= k <= n <= 5000 +// 0 <= Node.val <= 1000 + + public ListNode reverseKGroup(ListNode head, int k) { + if(k==1){//无意义直接返回原链表 + return head; + } + ListNode sumNode=new ListNode(0); + ListNode curr=sumNode; + + ListNode n=head; + Stack stack=new Stack<>(); + int i=0; + while (n!=null){ + if(i value = stack.iterator(); +// while (value.hasNext()) { +// sumNode.next=value.next(); +// sumNode=sumNode.next; +// } +// sumNode.next=null; +// } +// else {//i=k +// while (!stack.empty()){ +// sumNode.next=stack.pop(); +// sumNode=sumNode.next; +// } +// i=0; +// sumNode.next=null; +// } + + + } + while (!stack.empty()) { + Iterator value = stack.iterator(); + while (value.hasNext()) { + ListNode tmp=value.next(); + sumNode.next = tmp; + sumNode = sumNode.next; + + } + stack.clear(); + } + sumNode.next=null; + + return curr.next; + } + + public ListNode reverseKGroup2(ListNode head, int k) { + + ListNode sumNode=new ListNode(0); + ListNode curr=sumNode; + + ListNode n=head; + ListNode res=null; + int i=0; + while(n!=null){ + if(i4->5, + * 1->3->4, + * 2->6 + * ] + * 将它们合并到一个有序链表中得到。 + * 1->1->2->3->4->4->5->6 + * 示例 2: + * + * 输入:lists = [] + * 输出:[] + * 示例 3: + * + * 输入:lists = [[]] + * 输出:[] + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/Num11.java b/src/main/java/org/cc/leetcode/onehundred/twenty/Num11.java similarity index 97% rename from src/main/java/org/cc/leetcode/onehundred/Num11.java rename to src/main/java/org/cc/leetcode/onehundred/twenty/Num11.java index 80c64c62..cc596f96 100644 --- a/src/main/java/org/cc/leetcode/onehundred/Num11.java +++ b/src/main/java/org/cc/leetcode/onehundred/twenty/Num11.java @@ -1,4 +1,4 @@ -package org.cc.leetcode.onehundred; +package org.cc.leetcode.onehundred.twenty; /** * https://leetcode.cn/problems/container-with-most-water/ diff --git a/src/main/java/org/cc/leetcode/onehundred/twenty/Num12.java b/src/main/java/org/cc/leetcode/onehundred/twenty/Num12.java new file mode 100644 index 00000000..8f94ec72 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/twenty/Num12.java @@ -0,0 +1,119 @@ +package org.cc.leetcode.onehundred.twenty; + +/** + * https://leetcode.cn/problems/roman-to-integer/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num12 { + public static void main(String[] args) { + Num12 test=new Num12(); +// ListNode.printListNode(); + + String res=test.intToRoman(3); + System.out.println("res "+res); + } + + + String[] romachars=new String[]{ + "M", "CM","D","CD","C", "XC","L","XL","X", "IX","V","IV","I" + }; + + int[] nums=new int[]{1000, 900,500,400,100, 90,50,40,10, 9,5,4,1}; + public String intToRoman(int num) { + StringBuilder res = new StringBuilder(); + if(num>0) { + for (int i = 0; i < nums.length&&num>0; i++) { + String romachar = romachars[i]; + + while (num >= nums[i]) { + num -= nums[i]; + res.append(romachar); + } + } + } + return res.toString(); + } +} + + + +/**** + * 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 + * + * 字符 数值 + * I 1 + * V 5 + * X 10 + * L 50 + * C 100 + * D 500 + * M 1000 + * 例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 + * + * 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: + * + * I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 + * X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 + * C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 + * 给定一个罗马数字,将其转换成整数。 + * + * + * + * 示例 1: + * + * 输入: s = "III" + * 输出: 3 + * 示例 2: + * + * 输入: s = "IV" + * 输出: 4 + * 示例 3: + * + * 输入: s = "IX" + * 输出: 9 + * 示例 4: + * + * 输入: s = "LVIII" + * 输出: 58 + * 解释: L = 50, V= 5, III = 3. + * 示例 5: + * + * 输入: s = "MCMXCIV" + * 输出: 1994 + * 解释: M = 1000, CM = 900, XC = 90, IV = 4. + * + * + * 提示: + * + * 1 <= s.length <= 15 + * s 仅含字符 ('I', 'V', 'X', 'L', 'C', 'D', 'M') + * 题目数据保证 s 是一个有效的罗马数字,且表示整数在范围 [1, 3999] 内 + * 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。 + * IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。 + * 关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。 + * + * + * + * + * 羅馬數字共有7個,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。按照下述的規則可以表示任意正整數。需要注意的是罗马数字中没有“0”,與進位制無關。一般認為羅馬數字只用來記數,而不作演算。 + * + * 重複數次:一個羅馬數字重複幾次,就表示這個數的幾倍。 + * 右加左減: + * 在較大的羅馬數字的右邊記上較小的羅馬數字,表示大數字加小數字。 + * 在較大的羅馬數字的左邊記上較小的羅馬數字,表示大數字减小數字。 + * 左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV + * 但是,左減時不可跨越一個位值。比如,99不可以用IC(100-1)表示,而是用XCIX([100-10]+[10-1])表示。(等同於阿拉伯數字每位數字分別表示。) + * 左減數字必須為一位,比如8寫成VIII,而非IIX。 + * 右加數字不可連續超過三位,比如14寫成XIV,而非XIIII。(見下方“數碼限制”一項。) + * 加線乘千: + * 在羅馬數字的上方加上一條橫線或者加上下標的M,表示將這個數乘以1000,即是原數的1000倍。 + * 同理,如果上方有兩條橫線,即是原數的1000000(1000^{{2}})倍。 + * 數碼限制: + * 同一數碼最多只能连续出現三次,如40不可表示為XXXX,而要表示為XL。 + * 例外:由於IV是古羅馬神話主神朱庇特(即IVPITER,古羅馬字母裡沒有J和U)的首字,因此有時用IIII代替IV。 + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/twenty/Num13.java b/src/main/java/org/cc/leetcode/onehundred/twenty/Num13.java new file mode 100644 index 00000000..a3e97b04 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/twenty/Num13.java @@ -0,0 +1,141 @@ +package org.cc.leetcode.onehundred.twenty; + +import org.apache.commons.lang.StringUtils; + +/** + * https://leetcode.cn/problems/roman-to-integer/description/?languageTags=java + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num13 { + public static void main(String[] args) { + Num13 test=new Num13(); +// ListNode.printListNode(); +// int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; + + int[] tar={ 3,0,-2,-1,1,2}; + + int res=test.romanToInt("LVIII"); + System.out.println("res "+res); + } + + +// String[] romachars=new String[]{ +// "M", "CM","D","CD","C", "XC","L","XL","X", "IX","V","IV","I" +// }; +// int[] nums=new int[]{1000, 900,500,400,100, 90,50,40,10, 9,5,4,1}; + private int getVal(char c){ + switch (c){ + case 'I':return 1; + case 'V':return 5; + case 'X':return 10; + case 'L':return 50; + case 'C' :return 100; + case 'D' :return 500; + case 'M' :return 1000; + default:return 0; + } + } + public int romanToInt(String s) { + int pre=getVal(s.charAt(0)); + int sum=0 ; + if(StringUtils.isNotBlank(s)){ + for (int i = 1; i > res=test.threeSum(tar); Gson gson = new GsonBuilder().serializeNulls().create(); @@ -29,72 +29,50 @@ public static void main(String[] args) { System.out.println("res "+text); } - private void removeListNode(int i,List tarlist){ - if(tarlist==null||tarlist.size()==0){ - return; - }else { - if(tarlist.indexOf(i)==0){ - tarlist.remove(0); - } - } - } - public List> threeSum(int[] nums) { - Set> resset=new HashSet>(); - - //search res list - List tarlist=Arrays.stream(nums).boxed().collect(Collectors.toList()); - -// List numslist=Arrays.stream(nums).boxed().collect(Collectors.toList()); - - Arrays.stream(nums).boxed().collect(Collectors.toList()); -// int len=nums.length-1; -// int[] temparra= Arrays.stream(nums).toArray(); - if(nums==null||nums.length<2){ - return null; - }else { - for (int i = 0; i list=new ArrayList<>(); -// if((fir!=sen&&sen!=thi&&thi!=fir)||(fir==sen&&sen==thi&&thi==fir&&fir==0)){ - list.add(fir); - list.add(sen);list.add(thi); - Collections.sort(list); - resset.add(list); -// } - } - } + public List> threeSum(int[] nums) { + if(nums==null||nums.length<3){ + return null; } - List> reslist=new ArrayList>(resset); - return reslist; - } - //双指针查找数字 - private String findNum(List list,int num){ - String res=null; - //判断在外面做 - if(list==null||list.size()==0){ - - }else if(list.size()==1){ - if(list.get(0)==num){ - return num+""; + List sumlist=null; + Set> set=new HashSet>(); + Arrays.sort(nums); + int sta,end=0;//指针位置 + int sum,temp=0;//三数字相加结果 + int len= nums.length; + for (int i = 0; i < len; i++) { + temp=nums[i]; + if(temp>0){break;}//起始数字>0,直接退出 + sta=i+1; + end=len-1; + while (sta(); + sumlist.add(temp); + sumlist.add(nums[sta]); + sumlist.add(nums[end]); + set.add(sumlist); + + while(sta0){//end指针左移 + end--; + }else { + sta++; + } } - }else { - if(list.lastIndexOf(num)>-1){ - res=num+""; - return res; - } } - return res; + List> list=new ArrayList<>(set); + return list; } } diff --git a/src/main/java/org/cc/leetcode/onehundred/twenty/Num16.java b/src/main/java/org/cc/leetcode/onehundred/twenty/Num16.java new file mode 100644 index 00000000..d66e190b --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/twenty/Num16.java @@ -0,0 +1,101 @@ +package org.cc.leetcode.onehundred.twenty; + +import java.util.*; + +/** + * https://leetcode.cn/problems/container-with-most-water/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num16 { + public static void main(String[] args) { + Num16 test=new Num16(); +// ListNode.printListNode(); +// int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; +// 0,1,2 + int[] tar={-1,2,1,-4}; +//-4 -1 1 2 + int text=test.threeSumClosest(tar,1); + System.out.println("res "+text); + + + } + + + public int threeSumClosest(int[] nums, int target) { + if(nums==null||nums.length<3){ + return 0; + } +// ArrayList list=new ArrayList<>(); + Arrays.sort(nums); +// System.out.println("["+nums.toString()+"]"); + Map map=new HashMap<>();//key 距离 val 是三数之和 + int l,r=0; + int juli,sum=0; + int lastsum=nums[0]+nums[1]+nums[2]; + int[] array=new int[]{nums[0],nums[1],nums[2]}; + int lastjuli=Math.abs(target-lastsum); + + int len=nums.length; + for (int i = 0; i < len-2; i++) { + l=i+1; + r=len-1; + while(ljuli){// + array =new int[]{nums[i],nums[l],nums[r]}; + lastjuli=juli; + } + +// lastjuli=Math.min(juli,lastjuli); +// map.put(juli,sum); + if(ltarget){ + r--; + } +// l++; +// r--; + } + + } + return Arrays.stream(array).sum(); + } +} + + + +/**** + * 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。 + * + * 返回这三个数的和。 + * + * 假定每组输入只存在恰好一个解。 + * + * + * + * 示例 1: + * + * 输入:nums = [-1,2,1,-4], target = 1 + * 输出:2 + * 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。 + * 示例 2: + * + * 输入:nums = [0,0,0], target = 1 + * 输出:0 + * + * + * 提示: + * + * 3 <= nums.length <= 1000 + * -1000 <= nums[i] <= 1000 + * -104 <= target <= 104 + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/twenty/Num17.java b/src/main/java/org/cc/leetcode/onehundred/twenty/Num17.java new file mode 100644 index 00000000..7b9f82e5 --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/twenty/Num17.java @@ -0,0 +1,139 @@ +package org.cc.leetcode.onehundred.twenty; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * https://leetcode.cn/problems/letter-combinations-of-a-phone-number/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + */ +public class Num17 { + public static void main(String[] args) { + Num17 test=new Num17(); +// ListNode.printListNode(); +// int[] tar={-1,0,1,2,-1,-4}; +// int[] tar={3,-2,1,0}; + +String str="23"; +str="7"; + List res=test.letterCombinations(str); + Gson gson = new GsonBuilder().serializeNulls().create(); + String text = gson.toJson(res); + System.out.println("res "+text); + } + String[] str=new String[]{"00","11","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; + + private Map initMap(){ + Map map=new HashMap<>(); + for (int i = 0; i <10 ; i++) { + map.put(i+"",str[i]); + } + return map; + } + public List letterCombinations(String digits) { + System.out.println("digits:"+digits); + List reslist=new ArrayList<>(); + if(digits==null||digits.length()==0){ + return reslist; + }else if(digits.length()==1){ + String str= initMap().get(digits); + char[] chaarr=str.toCharArray(); + for (int i = 0; i map=initMap(); + char[] chars=digits.toCharArray(); + int i=1; + String[] temp=null; + while(i al=new ArrayList(); + for (int i = 0; i < a.length; i++) { + for (int j = 0; j al=new ArrayList(); + for (int i = 0; i < a.length; i++) { + for (int j = 0; j > res=test.fourSum(intarr,tar); + Gson gson = new GsonBuilder().serializeNulls().create(); + String text = gson.toJson(res); + System.out.println("res "+text); + } + + + public List> fourSum(int[] nums, int target) { + if(nums.length<4){ + return null; + }else { + Arrays.sort(nums); + + + } + return null; + + } +} + +/*** + * 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复): + * + * 0 <= a, b, c, d < n + * a、b、c 和 d 互不相同 + * nums[a] + nums[b] + nums[c] + nums[d] == target + * 你可以按 任意顺序 返回答案 。 + * + * + * + * 示例 1: + * + * 输入:nums = [1,0,-1,0,-2,2], target = 0 + * 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]] + * 示例 2: + * + * 输入:nums = [2,2,2,2,2], target = 8 + * 输出:[[2,2,2,2]] + * + * + * 提示: + * + * 1 <= nums.length <= 200 + * -109 <= nums[i] <= 109 + * -109 <= target <= 109 + * + * + * **/ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/onehundred/twenty/Num19.java b/src/main/java/org/cc/leetcode/onehundred/twenty/Num19.java new file mode 100644 index 00000000..15d3db2a --- /dev/null +++ b/src/main/java/org/cc/leetcode/onehundred/twenty/Num19.java @@ -0,0 +1,132 @@ +package org.cc.leetcode.onehundred.twenty; + +import com.google.gson.Gson; +import org.cc.leetcode.util.ListNode; + +import java.util.LinkedList; + +/** + * https://leetcode.cn/problems/remove-nth-node-from-end-of-list/ + * @ClassName : Num18 + * @Description : + * @param: + * @Author : CC + * @Date: 2023-04-20 15:33 + * + * 输入:head = [1,2,3,4,5], n = 2 + * 输出:[1,2,3,5] + * 示例 2: + * + * 输入:head = [1], n = 1 + * 输出:[] + * 示例 3: + * + * 输入:head = [1,2], n = 1 + * 输出:[1] + */ +public class Num19 { + public static void main(String[] args) { + Num19 test=new Num19(); + ListNode listnode=test.initListNode(); + ListNode res=test.removeNthFromEnd2(listnode,2); + Gson gson=new Gson(); + String text=gson.toJson(res); + System.out.println("res "+text); + + + } + public ListNode removeNthFromEnd2(ListNode head, int n) { + + if(head!=null){ + ListNode tempnode=head,nnode=head; + for (int i = 0; i link=new LinkedList<>(); + int len=1; + while (temp!=null){ + link.add(temp.val); + if(temp.next!=null){ + len++; + + } + temp=temp.next; + } + link.remove(link.size()-n);//去掉指定的元素 + if(link.isEmpty()){ + return null; + }else { + temp=root; + for (int val:link + ) { + ListNode node=new ListNode(val); + temp.next=node; + temp=temp.next; + } + return root.next; + } + } + + } +} + + + +/**** + * 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。 + * + * 返回这三个数的和。 + * + * 假定每组输入只存在恰好一个解。 + * + * + * + * 示例 1: + * + * 输入:nums = [-1,2,1,-4], target = 1 + * 输出:2 + * 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。 + * 示例 2: + * + * 输入:nums = [0,0,0], target = 1 + * 输出:0 + * + * + * 提示: + * + * 3 <= nums.length <= 1000 + * -1000 <= nums[i] <= 1000 + * -104 <= target <= 104 + * */ \ No newline at end of file diff --git a/src/main/java/org/cc/leetcode/util/ListNode.java b/src/main/java/org/cc/leetcode/util/ListNode.java index 5b5688f0..d4d5cdd0 100644 --- a/src/main/java/org/cc/leetcode/util/ListNode.java +++ b/src/main/java/org/cc/leetcode/util/ListNode.java @@ -45,10 +45,23 @@ public static void printListNode(ListNode node) { }else { System.out.println("printListNode: "); while (node!=null){ - System.out.println(node.val); + System.out.print(node.val+" "); node=node.next; } } + System.out.println("***************************************"); + } + public static void printListNode(String str,ListNode node) { + if(node==null){ + System.out.println(str+": is null"); + }else { + System.out.println(str+":"); + while (node!=null){ + System.out.print(node.val+" "); + node=node.next; + } + } + System.out.println("***************************************"); } diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/CASLock.java b/src/main/java/org/cc/thread/aqs/tulingfox/CASLock.java new file mode 100644 index 00000000..0b279a59 --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/CASLock.java @@ -0,0 +1,38 @@ +package org.cc.thread.aqs.tulingfox; + +import com.tuling.jucdemo.factory.UnsafeFactory; +import sun.misc.Unsafe; + +/** + * @author Fox + */ +public class CASLock { + + //加锁标记 + private volatile int state; + private static final Unsafe UNSAFE; + private static final long OFFSET; + + static { + try { + UNSAFE = UnsafeFactory.getUnsafe(); + OFFSET = UnsafeFactory.getFieldOffset( + UNSAFE, CASLock.class, "state"); + } catch (Exception e) { + throw new Error(e); + } + } + + public boolean cas() { + return UNSAFE.compareAndSwapInt(this, OFFSET, 0, 1); + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/ConditionTest.java b/src/main/java/org/cc/thread/aqs/tulingfox/ConditionTest.java new file mode 100644 index 00000000..0baa3267 --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/ConditionTest.java @@ -0,0 +1,52 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 等待唤醒机制 await/signal测试 + */ +@Slf4j +public class ConditionTest { + + public static void main(String[] args) { + Lock lock = new ReentrantLock(); + Condition condition = lock.newCondition(); + + new Thread(() -> { + lock.lock(); + try { + log.debug(Thread.currentThread().getName() + " 开始处理任务"); + //会释放当前持有的锁,然后阻塞当前线程 + condition.await(); + log.debug(Thread.currentThread().getName() + " 结束处理任务"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }).start(); + + new Thread(() -> { + lock.lock(); + try { + log.debug(Thread.currentThread().getName() + " 开始处理任务"); + + Thread.sleep(2000); + //唤醒因调用Condition#await方法而阻塞的线程 + condition.signal(); + log.debug(Thread.currentThread().getName() + " 结束处理任务"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + }).start(); + + + } +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo.java b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo.java new file mode 100644 index 00000000..888df119 --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo.java @@ -0,0 +1,39 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author Fox + * 同步执行 + */ +public class ReentrantLockDemo { + + private static int sum = 0; + private static Lock lock = new ReentrantLock(); + //private static TulingLock lock = new TulingLock(); + + public static void main(String[] args) throws InterruptedException { + + for (int i = 0; i < 3; i++) { + Thread thread = new Thread(()->{ + //加锁 + lock.lock(); + try { + // 临界区代码 + // TODO 业务逻辑:读写操作不能保证线程安全 + for (int j = 0; j < 10000; j++) { + sum++; + } + } finally { + // 解锁 + lock.unlock(); + } + }); + thread.start(); + } + + Thread.sleep(2000); + System.out.println(sum); + } +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo2.java b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo2.java new file mode 100644 index 00000000..322e9f3c --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo2.java @@ -0,0 +1,47 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.locks.ReentrantLock; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 可重入 + */ +@Slf4j +public class ReentrantLockDemo2 { + + public static ReentrantLock lock = new ReentrantLock(); + + public static void main(String[] args) { + method1(); + } + + + public static void method1() { + lock.lock(); + try { + log.debug("execute method1"); + method2(); + } finally { + lock.unlock(); + } + } + public static void method2() { + lock.lock(); + try { + log.debug("execute method2"); + method3(); + } finally { + lock.unlock(); + } + } + public static void method3() { + lock.lock(); + try { + log.debug("execute method3"); + } finally { + lock.unlock(); + } + } +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo3.java b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo3.java new file mode 100644 index 00000000..a03421fd --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo3.java @@ -0,0 +1,51 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.locks.ReentrantLock; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 可中断 + */ +@Slf4j +public class ReentrantLockDemo3 { + + public static void main(String[] args) throws InterruptedException { + ReentrantLock lock = new ReentrantLock(); + + Thread t1 = new Thread(() -> { + + log.debug("t1启动..."); + + try { + lock.lockInterruptibly(); + try { + log.debug("t1获得了锁"); + } finally { + lock.unlock(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + log.debug("t1等锁的过程中被中断"); + } + + }, "t1"); + + + lock.lock(); + try { + log.debug("main线程获得了锁"); + t1.start(); + //先让线程t1执行 + Thread.sleep(1000); + + t1.interrupt(); + log.debug("线程t1执行中断"); + } finally { + lock.unlock(); + } + + } + +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo4.java b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo4.java new file mode 100644 index 00000000..5ba61475 --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo4.java @@ -0,0 +1,59 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 锁超时 + */ +@Slf4j +public class ReentrantLockDemo4 { + + public static void main(String[] args) throws InterruptedException { + ReentrantLock lock = new ReentrantLock(); + + Thread t1 = new Thread(() -> { + + log.debug("t1启动..."); + // 注意: 即使是设置的公平锁,此方法也会立即返回获取锁成功或失败,公平策略不生效 +// if (!lock.tryLock()) { +// log.debug("t1获取锁失败,立即返回false"); +// return; +// } + + //超时 + try { + if (!lock.tryLock(1, TimeUnit.SECONDS)) { + log.debug("等待 1s 后获取锁失败,返回"); + return; + } + } catch (InterruptedException e) { + e.printStackTrace(); + return; + } + + try { + log.debug("t1获得了锁"); + } finally { + lock.unlock(); + } + + }, "t1"); + + + lock.lock(); + try { + log.debug("main线程获得了锁"); + t1.start(); + //先让线程t1执行 + Thread.sleep(2000); + } finally { + lock.unlock(); + } + + } + +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo5.java b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo5.java new file mode 100644 index 00000000..68511b97 --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo5.java @@ -0,0 +1,51 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 公平锁 + */ +@Slf4j +public class ReentrantLockDemo5 { + + public static void main(String[] args) throws InterruptedException { + //ReentrantLock lock = new ReentrantLock(true); //公平锁 + ReentrantLock lock = new ReentrantLock(); //非公平锁 + + for (int i = 0; i < 500; i++) { + new Thread(() -> { + lock.lock(); + try { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.debug(Thread.currentThread().getName() + " running..."); + } finally { + lock.unlock(); + } + }, "t" + i).start(); + } + // 1s 之后去争抢锁 + Thread.sleep(1000); + + for (int i = 0; i < 500; i++) { + new Thread(() -> { + lock.lock(); + try { + log.debug(Thread.currentThread().getName() + " running..."); + } finally { + lock.unlock(); + } + }, "强行插入" + i).start(); + + } + + } + +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo6.java b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo6.java new file mode 100644 index 00000000..8053715f --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/ReentrantLockDemo6.java @@ -0,0 +1,97 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author Fox + * 条件变量 + */ +@Slf4j +public class ReentrantLockDemo6 { + private static ReentrantLock lock = new ReentrantLock(); + private static Condition cigCon = lock.newCondition(); + private static Condition takeCon = lock.newCondition(); + + private static boolean hashcig = false; + private static boolean hastakeout = false; + + //送烟 + public void cigratee(){ + lock.lock(); + try { + while(!hashcig){ + try { + log.debug("没有烟,歇一会"); + cigCon.await(); + + }catch (Exception e){ + e.printStackTrace(); + } + } + log.debug("有烟了,干活"); + }finally { + lock.unlock(); + } + } + + //送外卖 + public void takeout(){ + lock.lock(); + try { + while(!hastakeout){ + try { + log.debug("没有饭,歇一会"); + takeCon.await(); + + }catch (Exception e){ + e.printStackTrace(); + } + } + log.debug("有饭了,干活"); + }finally { + lock.unlock(); + } + } + + public static void main(String[] args) { + ReentrantLockDemo6 test = new ReentrantLockDemo6(); + new Thread(() ->{ + test.cigratee(); + }).start(); + + new Thread(() -> { + test.takeout(); + }).start(); + + new Thread(() ->{ + lock.lock(); + try { + hashcig = true; + log.debug("唤醒送烟的等待线程"); + cigCon.signal(); + }finally { + lock.unlock(); + } + + + },"t1").start(); + + new Thread(() ->{ + lock.lock(); + try { + hastakeout = true; + log.debug("唤醒送饭的等待线程"); + takeCon.signal(); + }finally { + lock.unlock(); + } + + + },"t2").start(); + } + +} diff --git a/src/main/java/org/cc/thread/aqs/tulingfox/TulingLock.java b/src/main/java/org/cc/thread/aqs/tulingfox/TulingLock.java new file mode 100644 index 00000000..45e8aec7 --- /dev/null +++ b/src/main/java/org/cc/thread/aqs/tulingfox/TulingLock.java @@ -0,0 +1,46 @@ +package org.cc.thread.aqs.tulingfox; + +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +/** + * @author Fox + * + */ +public class TulingLock extends AbstractQueuedSynchronizer{ + + @Override + protected boolean tryAcquire(int unused) { + //cas 加锁 state=0 + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + + @Override + protected boolean tryRelease(int unused) { + //释放锁 + setExclusiveOwnerThread(null); + setState(0); + return true; + } + + public void lock() { + acquire(1); + } + + public boolean tryLock() { + return tryAcquire(1); + } + + public void unlock() { + release(1); + } + + public boolean isLocked() { + return isHeldExclusively(); + } + + +} \ No newline at end of file