LinkedList
Thread unsafe class, high execution efficiency
Link list structure, fast query, slow addition and deletion
Features unique to the LinkedList collection
Unique function name | Functional meaning |
---|---|
public void addFirst(Object e) | Insert element at the beginning of the list |
public void addLast(Object e) | Append element to end of list |
public Object getFirst() | Gets the first element of the list |
public Object getLast() | Gets the last element of the list |
public Object removeFirst() | Deletes the first element of the list and gets the first element |
public Object removeLast() | Deletes the last element of the list and gets the last element |
public class LinkedListDemo { public static void main(String[] args) { //Create a LinkedList collection object LinkedList<String> link = new LinkedList<>() ; //Add element // public void addFirst(Object e): inserts an element at the beginning of the list link.addFirst("hello") ; link.addFirst("world") ; link.addFirst("JavaEE") ; link.addFirst("Android") ; link.addLast("Php") ; //public Object getFirst(): get the first element of the list System.out.println(link.getFirst()); System.out.println(link.getLast()); // public Object removeFirst(): deletes the first element of the list and gets the first element System.out.println(link.removeFirst()); System.out.println(link.removeLast()); System.out.println(link); } }
Simulation stack structure features (LinkedList)
public class MyStack<T> { //Generics: defined on classes, methods and interfaces //String //Member variable, declaring a LinkedList type variable private LinkedList<T> link ; //String //Provides a parameterless construction method public MyStack(){ //Initialize link link = new LinkedList<>() ; } //The function of adding is provided by using addFirst() of LinkedList public void set(T t){//String link.addFirst(t);//Every time you add an element to the beginning of the list } //Provides the function of deletion, using the removeFirst() of LinkedList: delete and return the first element public <T> T get(){//Define the generic type on the method / / get the element String type return (T) link.removeFirst(); //Removefirst() --- > Object type } //Provide a judgment function public boolean isEmpty(){ return link.isEmpty() ; } } public class LinkeListTest { public static void main(String[] args) { //Create MyStack object MyStack<String> myStack = new MyStack<>() ; myStack.set("hello"); myStack.set("world"); myStack.set("JavaEE"); //Provide a judgment function /* if(!myStack.isEmpty()){ Object obj = myStack.get(); System.out.println(obj); }*/ while (!myStack.isEmpty()){ Object obj = myStack.get(); System.out.println(obj); } } }
Set
Unordered (inconsistent storage and retrieval), which can ensure the uniqueness of elements
HashSet
The underlying data structure is a hash table (bucket structure)
Thread unsafe classes ----- > asynchronous ----- > high execution efficiency
public class HashSetDemo { public static void main(String[] args) { //Create a HashSet collection object Set<String> set = new HashSet<>() ; //Add string element set.add("hello") ; set.add("hello") ; set.add("world") ; set.add("JavaEE") ; set.add("JavaEE") ; set.add("world") ; set.add("android") ; set.add("php") ; set.add("php") ; set.add(null) ; System.out.println(set); //Element unique } }
HashSet ensures element uniqueness (custom object)
- The HashSet collection depends on the add method - > the put method of HashMap
- First, the hash code value of the comparison element is the same ----- > hash()
- Also compare whether the member information is the same. The class corresponding to the self-defined storage must override the equals method of Object
- For this class of Student, hashCode() and equals must be given manually
- Hashset set cannot guarantee that the sequence iteration is constant!
public class Student { private String name ;//full name private int age ;//Age public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name.equals(student.name); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + age; return result; } } public class HashSetDemo2 { public static void main(String[] args) { //Create a HashSet collection object HashSet<Student> hs1 = new HashSet<>() ; Student s1 = new Student("Song Jiang",35) ; Student s2 = new Student("Song Jiang",35) ; Student s3 = new Student("Wu Song",30) ; Student s4 = new Student("Song Jiang",30) ; Student s5 = new Student("Wu Song",30) ; Student s6 = new Student("Lu Junyi",28) ; Student s7 = new Student("Lu Junyi",28) ; System.out.println("-------------------------------"); //System.out.println(s1.hashCode()); //System.out.println(s2.hashCode()); //Add to collection hs1.add(s1) ; hs1.add(s2) ; hs1.add(s3) ; hs1.add(s4) ; hs1.add(s5) ; hs1.add(s6) ; hs1.add(s7) ; //ergodic for(Student s : hs1){ System.out.println(s.getName()+"---"+s.getAge()); } } }
TreeSet
Disorder, element uniqueness
- The bottom layer depends on the TreeMap set. The red black tree structure (also known as "self balanced binary tree structure") can realize the natural sorting of maps and the sorting of comparators, depending on the construction method used
Construction method of TreeSet
Constructor name | Method meaning |
---|---|
public TreeSet() | Construct an empty tree to realize the natural sorting of elements |
public class TreeSetDemo { public static void main(String[] args) { // public TreeSet() //Integer type TreeSet<Integer> ts = new TreeSet<>() ; //The Intger element implements the Comparable interface -- it can be sorted naturally according to the elements (ascending by default) //Add element ts.add(20) ; ts.add(17) ; ts.add(17) ; ts.add(18) ; ts.add(24) ; ts.add(23) ; ts.add(24) ; ts.add(19) ; //Traversal set TreeSet for(Integer i:ts){ System.out.println(i); } } }
TreeSet sort (custom object) (natural sort)
Main conditions: sort according to the age of students from small to large
//Implement natural sorting and implement an interface Comparable public class Student implements Comparable<Student>{ private String name ;//full name private int age ;//Age public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } //Sort code @Override public int compareTo(Student s) { //You need to compare with the student object later //Main condition: it is sorted according to age from small to large //Define a variable //Age int type /* int num = this.age - s.age ; // int num = s.age - this.age ;//From big to small //Secondary conditions: the same age, but also compare whether the contents of the name are the same int num2 = (num==0)?(this.name.compareTo(s.name)):num; //Dictionary order comparison of strings //gaoyuanyuan //jacky return num2;*/ public class TreeSetDemo2 { public static void main(String[] args) { //Create TreeSet, parameterless construction method TreeSet<Student> ts = new TreeSet<>() ; //Create several student objects Student s1 = new Student("gaoyuanyuan",42) ; Student s2 = new Student("gaoyuanyuan",42) ; Student s3 = new Student("jacky",40) ; Student s4 = new Student("rose",40) ; Student s5 = new Student("tomcat",35) ; Student s6 = new Student("jeffry",35) ; Student s7 = new Student("liushishi",54) ; Student s8 = new Student("liudehua",60) ; //add to ts.add(s1) ; //Because of the user-defined objects stored in the current collection, in order to realize natural sorting, the class in which the elements are located must implement the comparable interface ts.add(s2) ; ts.add(s3) ; ts.add(s4) ; ts.add(s5) ; ts.add(s6) ; ts.add(s7) ; ts.add(s8) ; //ergodic for(Student s : ts){ System.out.println(s.getName()+"---"+s.getAge()); }
TreeSet sort (custom object) (comparator sort)
The comparator sort depends on the construction method
public class Student { private String name ;//full name private int age ;//Age public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name.equals(student.name); } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + age; return result; } } public class MyComparator implements Comparator<Student> { @Override public int compare(Student s1, Student s2) { //Main conditions: sort according to the age of students from small to large //S1 --- > is this in the natural sorting just now //S2 --- > is s in the natural sorting just now int num = s1.getAge() - s2.getAge() ; //If the age is the same, compare the names int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ; return num2; } } public class TreeSetDemo { public static void main(String[] args) { //Create TreeSet collection object // public TreeSet(Comparator<? super E> comparator) //MyComparator myComparator = new MyComparator() ; // Method 1: interface subclass object //Method 2: anonymous inner class of interface TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //Main conditions: sort according to the age of students from small to large //S1 --- > is this in the natural sorting just now //S2 --- > is s in the natural sorting just now int num = s1.getAge() - s2.getAge() ; //If the age is the same, compare the names int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ; return num2; } }) ; //Create several student objects Student s1 = new Student("gaoyuanyuan",42) ; Student s2 = new Student("gaoyuanyuan",42) ; Student s3 = new Student("jacky",40) ; Student s4 = new Student("rose",40) ; Student s5 = new Student("tomcat",35) ; Student s6 = new Student("jeffry",35) ; Student s7 = new Student("liushishi",54) ; Student s8 = new Student("liudehua",60) ; ts.add(s1) ; ts.add(s2) ; ts.add(s3) ; ts.add(s4) ; ts.add(s5) ; ts.add(s6) ; ts.add(s7) ; ts.add(s8) ; for (Student s:ts) { System.out.println(s.getName()+"---"+s.getAge()); } } }
Map
Map set: an object whose key is mapped to a value. A map set can have multiple values, but the key must be unique!
Functions of Map collection
Function name | Functional meaning |
---|---|
V put(K key,V value) | Add key value pair element |
V remove(Object key) | Delete the specified key and return the value corresponding to the deleted key |
void clear() | Violent deletion |
boolean containsKey(Object key) | Whether to include the specified key (mostly used) |
boolean containsValue(Object value) | Whether to include the specified value |
public class MapDemo { public static void main(String[] args) { //Creating a Map collection: Interface //By default, the HashMap collection treemap (sorted by element) is used Map<String,String> map = new HashMap<String,String>() ; System.out.println(map); //Add function // String result = map.put("article", "Mayi"); // System.out.println(result); map.put("article", "Mai Li"); map.put("Wang Baoqiang","Ma Rong") ; map.put("Guo Yang","little dragon maiden") ; map.put("Guo Jing","Huang Rong") ; // String result2 = map.put("article", "Yao Di"); // System.out.println(result2); map.put("article", "Yao di"); System.out.println("---------------------------------"); // System.out.println(map.remove("Yang Guo"); // map.clear(); System.out.println(map.containsKey("Jay Chou")) ; System.out.println(map.containsKey("Wang Baoqiang")) ; System.out.println(map.containsValue("Rong Guo")) ; System.out.println(map.containsValue("little dragon maiden")) ; System.out.println(map); } }
Traversal mode of Map collection
- Method 1: get the set of all K (the set of keys) and get the value through the key
- Method 2: get all key value pairs object map Entry < K, V > ("marriage certificate")
Get all keys through the key value pair object ("marriage certificate man")
Get all values from the key value pair object ("marriage certificate woman")
public class MapDemo2 { public static void main(String[] args) { //Create a Map collection object Map<String,String> map = new HashMap<>() ; //Add element map.put("linghu chong","invincible eastern") ; map.put("Guo Yang","little dragon maiden") ; map.put("Chen Xuanfeng","Mei Chaofeng") ; map.put("Guo Jing","Huang Rong") ; // Set < k > keyset(): get the set of all keys in the current Map set Set<String> keySet = map.keySet(); //The first method is recommended //Enhanced for traversal for(String key: keySet){ //Get all key elements // V get(Object key): get the value through the key String value = map.get(key); System.out.println(key+"="+value); } System.out.println("--------------------------------------"); //Mode 2: //Set<Map.Entry<K,V>> entrySet() Set<Map.Entry<String, String>> entry = map.entrySet(); //Enhanced for: traversing key value pairs to get objects for(Map.Entry<String, String> en: entry){ //Get keys and values //K getKey() // V getValue() String key = en.getKey(); String value = en.getValue(); System.out.println(key+"="+value); } } }
HashMap
The put method of HashMap depends on hashCode() and equals methods. The key type must override the hashCode and equals methods of Object class to ensure that the key is unique!
public class HashMapDemo { public static void main(String[] args) { //Create a Map collection object HashMap<Student,String> map = new HashMap<>() ; //Create several student objects Student s1 = new Student("article",35) ; Student s2 = new Student("article",35) ; Student s3 = new Student("article",37) ; Student s4 = new Student("Pan Weibai",40) ; Student s5 = new Student("You Ting Zhao",39) ; Student s6 = new Student("Cai Xukun",38) ; Student s7 = new Student("Cai Xukun",38) ; Student s8 = new Student("Xiao Zhan",30) ; map.put(s1,"Football") ; map.put(s2,"Basketball") ; map.put(s3,"Football") ; map.put(s4,"Drug") ; map.put(s5,"Gao Yuanyuan") ; map.put(s6,"Table Tennis") ; map.put(s7,"Basketball") ; map.put(s8,"acting") ; //ergodic Set<Student> students = map.keySet(); for(Student key :students){ //Get value by key String hobit = map.get(key); System.out.println(key.getName()+"---"+key.getAge()+"---"+hobit); } } }
TreeMap
TreeMap: red black tree structure - the keys of the Map are sorted by conditions - the keys are user-defined
- TreeMap<Integer,String>
- TreeMap<Student,String>
public class TreeMapDemo { public static void main(String[] args) { //Create a TreeMap collection object // TreeMap<Student,String> tm = new TreeMap<>() ; // Parameterless construction method: natural sorting: prerequisite: the type of key must be compatible //Comparator sort: anonymous inner class TreeMap<Student,String> tm = new TreeMap<>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //Main conditions: Students' age is sorted from big to small int num = s2.getAge() - s1.getAge() ; //If the age is the same, compare whether the contents of the name are the same int num2 = (num==0)? (s1.getName().compareTo(s2.getName())):num ; return num2; } }) ; //Create student object Student s1 = new Student("Tang Bohu",38) ; Student s2 = new Student("Tang Bohu",38) ; Student s3 = new Student("Qiu Xiang",30) ; Student s4 = new Student("Zhu Zhishan",40) ; Student s5 = new Student("Zhu Zhishan",45) ; Student s6 = new Student("Wen Zhengming",39) ; Student s7 = new Student("Pomegranate sister",20) ; Student s8 = new Student("Dongxiang",18) ; Student s9 = new Student("Xu Xiang",18) ; tm.put(s1,"the ming dynasty") ; tm.put(s2,"Song dynasty") ; tm.put(s3,"Qing Dynasty") ; tm.put(s4,"the ming dynasty") ; tm.put(s5,"modern") ; tm.put(s6,"the tang dynasty") ; tm.put(s7,"Song dynasty") ; tm.put(s8,"the ming dynasty") ; tm.put(s9,"modern") ; Set<Student> students = tm.keySet(); for(Student key :students){ String value = tm.get(key); System.out.println(key.getName()+"---"+key.getAge()+"---"+value); } } }
Simulated landlords (card order)
public class PokerTest2 { public static void main(String[] args) { //1) Card box //Create a card box map: HashMap < integer, string > key: number value: card HashMap<Integer,String> hm = new HashMap<>(); //Create an ArrayList collection: storage number ArrayList<Integer> arrayList = new ArrayList<>() ; //2) Deck //Create an array of points String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"} ; //Create Decor array String[] colors = {"♥","♠","♣","♦"} ; //Splicing //Number of definition cards: starting from 0 int index = 0 ; for(String number:numbers){ for(String color:colors){ String porker = number.concat(color); //Add numbers and cards to the HashMap collection hm.put(index,porker) ; //Store numbers for ArrayList separately arrayList.add(index) ; index ++ ; } } //Add Wang and Wang to the HashMap set, and add Wang and Wang numbers to the ArrayList hm.put(index,"Xiao Wang") ; arrayList.add(index) ; index ++ ; hm.put(index,"king") ; arrayList.add(index) ; // System.out.println(arrayList); //3) Shuffle: random permutation ArrayList < integer > shuffles numbers Collections.shuffle(arrayList); // System.out.println(arrayList); //4) Licensing /* In order to ensure the order of cards, the number is also issued * All three are TreeSet < integer > sets * Create a collection: diPai * Judgment: * If the corner mark > = the whole size of the card box () - 3 cards * If corner mark% 3 = = 0, the first person's * If corner mark% 3 = = 1, the second person's * %3 == 2 Third person's */ TreeSet<Integer> player1 = new TreeSet<>() ; TreeSet<Integer> player2 = new TreeSet<>() ; TreeSet<Integer> player3 = new TreeSet<>() ; //a hand TreeSet<Integer> diPai = new TreeSet<>() ; for(int x = 0 ;x < arrayList.size() ; x ++){ //0 start if(x >= arrayList.size()-3){ diPai.add(arrayList.get(x)) ; }else if(x % 3 == 0 ){ player1.add(arrayList.get(x)) ; }else if(x % 3 == 1){ player2.add(arrayList.get(x)) ; }else if(x % 3 ==2){ player3.add(arrayList.get(x)) ; } } //Look at cards: / / look at cards: everyone can look at cards and can also look at cards. Therefore, looking at cards encapsulates a function lookPoker("Zhang Junjie",player1,hm); lookPoker("Gao Yuanyuan",player2,hm); lookPoker("You Ting Zhao",player3,hm); lookPoker("a hand",diPai,hm); } public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer,String> hm){ //Player 1's card is: xxx //Player 2's card is: xxx System.out.print(name+"Your card is:"); //Traverse the TreeSet collection to get each number for(Integer key: ts){ //Get each number --- the key number in the HashMap set String poker = hm.get(key); //Get the value through the key in the large Map collection System.out.print(poker+" "); } System.out.println(); } }
The difference between a Map Collection and a Collection collection
- Collection collection: only one type of collection can be stored. Collection is simply "single"
- Map set: there are two types: key type and value type. Map < K, V > simply remember "husband and wife pair"
Collections
Collections: tool class for collection operations
Collections static function
Static function name | Functional meaning |
---|---|
public static <T extends Comparable<? super T>> void sort(List list) | Sort in natural ascending order (for the List set) |
public static void sort(List list,Comparator<? super T> c) | Sort by comparator for List collection |
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> | Gets the maximum value of the List in the current natural order |
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> | Gets the minimum value of the List in the current natural order |
public static void reverse(List<?> list) | Reverse the order of the List collection |
public static void shuffle(List<?> list) | Random permutation |
public class CollectionsDemo1 { public static void main(String[] args) { //Create List collection List<Integer> list = new ArrayList<>() ; //Add element list.add(10) ; list.add(50) ; list.add(15) ; list.add(25) ; list.add(5) ; list.add(12) ; System.out.println(list); System.out.println("---------------------------------"); //public static <T extends Comparable<? super T>> void sort(List<T> list): Collections.sort(list); System.out.println(list); System.out.println("----------------------------------"); //public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> Integer max = Collections.max(list); System.out.println(max); System.out.println("----------------------------------"); System.out.println(Collections.min(list)); System.out.println("-----------------------------------"); Collections.reverse(list);//reversal System.out.println(list); System.out.println("------------------------------------"); // Public static void shuffle (list <? > list): random displacement Collections.shuffle(list); System.out.println(list); }
Sort List in natural ascending order
public class CollectionsTest { public static void main(String[] args) { //Create a List collection object List<Student> list = new ArrayList<>() ; //Create several student objects Student s1 = new Student("gaogaoyuan",42) ; Student s2 = new Student("gaogaoyuan",40) ; Student s3 = new Student("liushishi",42) ; Student s4 = new Student("wanglihong",45) ; Student s5 = new Student("wenzhang",38) ; Student s6 = new Student("huazi",35) ; Student s7 = new Student("huazi",32) ; Student s8 = new Student("zhangjunjie",20) ; //add to list.add(s1) ; list.add(s2) ; list.add(s3) ; list.add(s4) ; list.add(s5) ; list.add(s6) ; list.add(s7) ; list.add(s8) ; //sort //Collections.sort(list); // Natural ascending sort: the type currently stored in the collection must be compatible //Sorting with comparator: for List collection //Public static < T > void sort (List < T > List, comparator <? Super T > C): sort the List set according to the comparator Collections.sort(list, new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { int num = s1.getAge() - s2.getAge() ; int num2 = (num==0)?(s1.getName().compareTo(s2.getName())):num ; return num2; } }); for(Student s:list){ System.out.println(s.getName()+"---"+s.getAge()); } } }
System
System class: cannot instantiate
Member variables of the System class
Member variable name | Variable meaning |
---|---|
public static final InputStream in | Standard input stream |
public static final PrintStream out | Standard output stream |
public static final PrintStream err | Error output stream |
System.exit(0) | The jvm exits, and 0 indicates normal termination |
public static void gc() | Manually opening the garbage collector will recycle objects without more references in memory! |
public class Person { private String name; private int age ; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } //Override the finalize() method of the Object class @Override protected void finalize() throws Throwable { System.out.println("gc Recycling objects without more references"+this); super.finalize(); } } public class SystemDemo { public static void main(String[] args) throws IOException { // System.err.println("this is the error output stream"); InputStream in = System.in ; //Byte output stream //The scanner / bufferedread character can be used for keyboard entry to buffer the input stream: read data Scanner sc = new Scanner(in) ; //The InputStream parameter is passed inside System.out.println("helloworld"); System.out.println("--------------------------------------"); PrintStream ps = System.out ; //Byte print stream //Println (any data type): some jobs in the PrintStream stream ps.println(10); ps.println(12.56); System.out.println("----------------------------------------"); //Create Person object Person p = new Person("Gao Yuanyuan",41) ; System.out.println(p.getName()+"---"+p.getAge()); p = null ; //Manual garbage collector (no need to manually open the garbage collector, automatic recycling)! System.gc() ; //protected void finalize() throws Throwable: you need to start the garbage collector through the jvm to recycle objects without more references /*int num = Runtime.getRuntime().availableProcessors(); System.out.println(num);*/ // Runtime.getRuntime().exec("notepad") ; // Runtime.getRuntime().exec("calc") ; } }
Throwable (exception)
Throwable: contains all errors and exceptions! It is a superclass (parent class)
Error
Very serious problem (not much related to the code)
Exception
- Compile time exception and runtime exception: problems occur during the running of the program (code writing is not rigorous)
- As long as it is not a subclass of RuntimeException, it is a compile time exception
The difference between compile time exceptions and run time exceptions
- Runtime exception:
The caller can perform display processing (try... catch... / throws) for problems caused by general programmers' loose logical structure
It can also be processed through logical statements without display processing! - Compile time exception:
The caller must display processing. If it is not processed, the compilation cannot pass, and the program cannot run
public class ExceptionDemo3 { public static void main(String[] args) throws Exception { method1() ;//caller /* try { method2() ; } catch (ParseException e) { System.out.println("There's a problem with parsing "); }*/ method2(); } //Compile time exception private static void method2() throws ParseException,ClassNotFoundException,Exception { //String date text -- > java util. Date Date object (parse) //Exception caught The caller will not process /* try{ String s = "2021-8-3" ; //Create a SimpleDateFormat object SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ; Date dat = sdf.parse(s) ; //parse The method itself has an exception, throws ParseException }catch (ParseException e){ System.out.println("There's a problem with parsing "); }*/ //Use throws in the current method String s = "2021-8-3" ; //Create a SimpleDateFormat object SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ") ; Date dat = sdf.parse(s) ; } //Runtime exception private static void method1() { //Display handling (exception handling method can be used: catch / throw throws, just use him) /* try{ int a = 10 ; int b = 0 ; System.out.println(a/b); }catch (Exception e){ System.out.println("The divisor is 0 "); }*/ //No display processing was done int a = 10 ; int b = 0 ; if(b!=0){ System.out.println(a/b); }else{ System.out.println("The divisor is 0..."); } }
try...catch...finally
Deformation format try{ //Possible problem codes }catch(Exception class name variable name){ //Handling exceptions }
try{ //Possible problem codes }catch(Exception class name variable name){ //Handling exception 1 }catch(Exception class name variable name){ //Handling exception 2 }
//Multithreading: jdk5 later: Lock: interface (lock: repeatable mutex) try{ //Possible problem codes }finally{ //Free resources (system resources) }
public class ExceptionDemo2 { public static void main(String[] args) { //method1() ; // method2() ; //method3() ; method4() ; } /* jdk7 try provided later{ Possible problem codes }catch(Exception class name 1 | exception class name 2 | exception class name 3 Variable name) {/ / exception class name must be of the same level Handling exceptions } */ private static void method4() { try { int a = 10; int b = 0; int[] arr = {4, 5, 6}; System.out.println(a / b); System.out.println(arr[0]); System.out.println(arr[3]); } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {//Contains all compile time / run time exceptions System.out.println("Something's wrong with the program..."); } } //Using TRT catch... catch... catch... Large exceptions cannot be placed first private static void method3() { try { int a = 10; int b = 1; //May be 0 int[] arr = {4, 5, 6}; arr = null; //Null value System.out.println(a / b); System.out.println(arr[0]); System.out.println(arr[3]); } catch (Exception e) {//Contains all compile time / run time exceptions System.out.println("Something's wrong with the program..."); } /* }catch (ArrayIndexOutOfBoundsException e){ System.out.println("Accessed index '') that does not exist in the array; }catch(ArithmeticException e){// Create the current exception class object through the jvm. If the current e type matches, a catch statement will be generated System.out.println("Divisor cannot be 0 ""); }*/ } //Unified processing for multiple exceptions, try catch... catch private static void method2() { try{ int a = 10; int b = 1 ; //May be 0 int[] arr = {4,5,6} ; arr = null ; //Null value System.out.println(a/b); System.out.println(arr[0]); System.out.println(arr[3]); }catch (ArrayIndexOutOfBoundsException e){ System.out.println("An index that does not exist in the array was accessed"); }catch(ArithmeticException e){// Create the current exception class object through the jvm. If the current e type matches, a catch statement will be generated System.out.println("Divisor cannot be 0"); }catch (Exception e){ System.out.println("Something's wrong with the program..."); } } //Try the code that may have problems Catch (not recommended) private static void method1() { try{ int a = 10; int b = 0 ; System.out.println(a/b); }catch (ArithmeticException e){ System.out.println("Divisor cannot be 0"); } //Create an array try{ int[] arr = {4,5,6} ; System.out.println(arr[0]); System.out.println(arr[3]); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Accessed an index that does not exist in the array"); } } }
throws
Interview questions (difference between throws and throw)
- Common ground: they are thrown
- Different usage:
- 1) Different use positions
throws:
a) Throw an exception on the method declaration
b) The method name can be followed by multiple exception class names separated by commas!
throw
a) In a logical statement in the body of a method
b) It can only be followed by an exception object, not a class name - 2) Does the caller handle different
Throws: the caller must perform display processing (try... catch/throws), otherwise an error will be reported
throw: the caller does not need to display processing. Generally, it is processed in a logical statement - 3) Is the abnormality positive
throws: on a method, there may be a problem in the code executing a method (indicating a possibility of exception)
throw: this exception is bound to be executed when a piece of code is executed (indicating the certainty of an exception) - 4
Throws - > hand over the specific processing to the jvm - print the exception information on the console through the jvm
The underlying source code is displayed, and the current error message string will be displayed
Throw --- > there is a problem with a piece of code in the program: just print the exception class name (jvm handling)
public class ExceptionDemo5 { public static void main(String[] args) throws ParseException { // // try { // method(); // } catch (ParseException e) { // System.out.println("solved the problem...); // } method(); // method2(); } //throw private static void method2() throws ArithmeticException { int a = 10 ; int b = 0 ; //Logical statement if(b!=0){ System.out.println(a/b); }else{ //Throw an object //throw anonymous object new XXXException(); throw new ArithmeticException() ; } } //throws private static void method() throws ParseException { //Set string - > date String source = "2021-8-3" ; //Create a SimpleDateFormat object SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ") ; //analysis Date date = sdf.parse(source) ; System.out.println(date); } }
finally
finally usage
- characteristic:
Release the relevant resources, and the code must be executed
Unless finally, the JVM exits!
public class ExceptionDemo6 { public static void main(String[] args) { try{ String source = "2021-8-3" ; //Create a SimpleDateFormat object SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ") ; //analysis Date date = sdf.parse(source) ; System.out.println(date); }catch (ParseException e){ //Use the functions in Throwabl //String result = e.getMessage();// Get message string // System.out.println(result); // String result = e.toString(); // System.out.println(result); e.printStackTrace(); System.exit(0); }finally{ //finally statement code must be executed! //Release resources System.out.println("Current system resources need to be released"); //JDBC (connection object / execution object Statement) //IO stream (create stream object, release stream object - system resources) //Inside the framework: Mybatis(JDBC encapsulation): execute the object SqlSession } //Shortcut key: for try --- catch --- finally: Alt + Ctrl + T --- > try Catch: capture } }
Interview question (if an exception is caught in a method, but the method has a return value type, will the finally code be executed if a return statement appears in the catch statement?)
- finally, it will execute, but now the code has formed a return path in the catch statement, and it will record that the final return is 30;finally, it is used to release resources, rarely involving business code; Will be executed unless the jvm exits!
public class Test { public static void main(String[] args) { int num = getNum(10) ;// i=10 System.out.println(num); } private static int getNum(int i) { try{ i = 20 ; //i = 20 ; System.out.println(i/0); //Divisor is 0 }catch (ArithmeticException e){ i = 30 ; //i =30 return i ; // Return I = return 30: the return path has been formed in the catch statement, and the return result is 30 }finally { //finally, the code will execute unless the jvm exits i = 40 ; // i = 40 // return i ; } return i; //30 } }
Binary search algorithm
- The prerequisite array must be ordered. If the array itself is out of order, let's query the elements, sort them first, and then find them! (conditional requirements are sorted first and then queried
- If there are no conditional requirements, you can only use the basic element lookup method: from beginning to end)
- If the requirements clearly require manual writing, you can use tools directly!
Arrays tool class:
- It provides sorting sort (sorting by any array): ascending sorting of elements, Integer,String
- It provides a binary search method (any type of query, int key)
public class BinarySearch { public static void main(String[] args) { //Known array, static initialization int[] arr = {11,22,33,44,55} ; //Call the binary search method to query int index = binarySearch(arr, 22); System.out.println(index); int index2 = binarySearch(arr,66) ; System.out.println(index2); int index3 = binarySearch(arr,44) ; System.out.println(index3); System.out.println("-----------------------------------"); int index4 = Arrays.binarySearch(arr, 55); System.out.println(index4); int index5 = Arrays.binarySearch(arr, 66); System.out.println(index5); } //Return value int //Method parameters: array, query elements public static int binarySearch(int[] arr,int target){ //Prevent null pointer exceptions if(arr!=null){ //Define the minimum index of the array: int min = 0 ; //Define maximum index int max = arr.length -1 ; //Use loop while while(min<=max){ //Site index in calculation int mid = (min+max)/2 ; //If the element corresponding to the current location is smaller than the element to be found if(target < arr[mid]){ //Left half area: continue to half max = mid -1 ; }else if(target > arr[mid]){ //Right area: continue to fold in half min = mid + 1 ; }else{ //Yes return mid ; } } } //If it is not found after the loop ends, - 1 is returned return -1 ; } }
Thread
process
-
Process:
Independent unit of system resources that can be called!
thread
-
Thread:
Belonging to the smallest unit of execution in a program (a task line in a process)
A process is composed of multiple threads. Multiple threads ----- > thread group
Thread state (lifecycle)
-
NEW, NEW status
When the program uses new to create a thread, the thread is in a new state. At this time, just like other java objects, the JVM allocates memory and initializes the value of member variables
-
RUNNABLE, execution status
In fact, it can be subdivided into two states: ready and running
-
BLOCKED, BLOCKED
The running thread encounters a special situation, such as synchronization, waiting for I/O operation to complete, etc Threads entering the blocking state will give up CPU resources and temporarily stop their execution
-
WAITING, WAITING
Sometimes, when a thread in a runnable state changes to a waiting state, it will wait for another thread to execute a task. A thread in a waiting state can continue to execute only if it is notified by another thread to go to the runnable state
-
TIMED_WAITING, timeout
Timed wait state is an upgraded version of wait state. It will have a timer to automatically wake up the thread object after a specific time and put it into ready state
-
TERMINATED, TERMINATED state (dead state)
That is, the dead state indicates that the thread is terminated This state is entered when the thread successfully completes execution, throws an uncapped Exception and Error, or calls the thread's stop method
Interview question (is jvm multithreaded?)
Is multithreaded:
There are at least two threads
User thread main, and when creating an object, when the object is used up, it needs to be recycled by the garbage collector;
The jvm starts a garbage collection thread for no more reference objects!
- Can the java language enable multithreading?
Start thread ----- > start process ----- Java language cannot start process - start process with the help of underlying language C language
Encapsulated into local methods - > JDK provides classes: encapsulated methods in Thread
Start thread: start()
Construction method of Thread class
Constructor name | Method meaning |
---|---|
Thread(String name) | Create a thread class object and set the name |
Member method of Thread class
Member method name | Method meaning |
---|---|
public final String getName() | Get thread name |
public final void setName(String name) | Set thread name |
Static constant field of the tree class
Static constant field name | Field meaning |
---|---|
public static final int MAX_PRIORITY 10 | Maximum priority |
public static final int MIN_PRIORITY 1 | Minimum priority |
public static final int NORM_PRIORITY 5 | Default Priority |
public final void setPriority(int newPriority) | Set thread priority |
public final int getPriority() | Get priority |
- The higher the priority: the greater the preemption of CPU execution power
- Low priority: the smaller the preemption of CPU execution power
- Default priority: more random
public class MyThread2 extends Thread { //t1,t2 @Override public void run() { for(int x = 0 ; x < 100 ; x ++){ //Get thread name System.out.println(this.getName()+":"+x); } } } public class ThreadDemo2 { public static void main(String[] args) {//User thread //Create an object of the MyThread2 class MyThread2 t1 = new MyThread2() ; MyThread2 t2 = new MyThread2() ; MyThread2 t3 = new MyThread2() ; // public final void setName(String name): sets the thread name t1.setName("Hong Xuejia") ; t2.setName("Zhang Junjie") ; t3.setName("Gao Yuanyuan"); t1.setPriority(10); //Maximum priority t2.setPriority(1);//Minimum priority int num1 = t1.getPriority(); int num2 = t2.getPriority(); int num3 = t3.getPriority(); System.out.println(num1+"---"+num2+"---"+num3); //Start thread t1.start(); t2.start(); t3.start(); } }
Implementation method of creating thread 1
- 1. Declare a class as a subclass of Thread
- 2. This subclass should override the run method of Thread class
- 3. You can then allocate and start instances of subclasses.
start() instead of run() is used to start the thread
//Thread class public class MyThread extends Thread { //Override the method of the Thread class @Override public void run() { //In the run method: generally time-consuming operations for(int x = 0 ; x < 200 ; x ++){ System.out.println(x); } } } public class ThreadDemo { public static void main(String[] args) { //3) Create a subclass object of the Thread class MyThread my1 = new MyThread() ;//First thread object MyThread my2 = new MyThread() ; //Second thread object //4) Start //my1.run(); //my2.run(); /* my1.start(); my1.start(); my1 Just represents a thread object my1 Call the start method twice ----- > illegalthreadstateexception: illegal thread state exception start()Original code: verify the current thread status: if the thread has been started, it cannot be started again */ my1.start();//start(): a jvm calls the underlying run method, and concurrent execution occurs my2.start(); } }
Use mode 1 to realize multi window ticket selling
- The cinema has three windows and sells 100 tickets together
public class SellTicket extends Thread { //Need to ensure that tickets are shared: use static modification public static int tickets = 100 ; //Override run method //st1,st2,st3 @Override public void run() { //There are always tickets while(true){ //Simulating network latency: the process of sleep try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if(tickets>0){ //100>0 System.out.println(getName()+"The second is being sold"+(tickets--)+"Ticket"); } /** * Reasons for the same ticket: Existence: atomic operation (+ +, --: simple and most direct operation) / delayed operation of the thread * st1(Window 1) --- > ticket record 100th ticket * st3(Window 3) - -- > window 1 is ready to execute ticket--(100-1=99), has seized the execution right, and is selling 100 tickets * * */ } } } public class SellTicketTest { public static void main(String[] args) { //Create three windows SellTicket st1 = new SellTicket() ; SellTicket st2 = new SellTicket() ; SellTicket st3 = new SellTicket() ; //Set thread name st1.setName("Window 1"); st2.setName("Window 2"); st3.setName("Window 3"); //Start thread st1.start() ; st2.start() ; st3.start() ; } }
Disadvantages of mode 1
Mode 1 there are disadvantages in the creation of multithreading
- 1) It is an inheritance relationship with "limitations"
- 2) The concept of resource sharing cannot be embodied because the Thread class uses a static proxy (design pattern)
Implementation of creating thread 2
- 1) The custom class implements the Runnable interface
- 2) Override the run method of the Runnable interface
- 3) In the main user thread
You can assign instances of classes (create instances of classes) - 4) Create the current class object, then create the Thread class object, and pass the current class object as a parameter
Current class ----- > "resource sharing class"
Thread(Runnable target, String name) - 5) Start the threads separately!
public class MyRunnable implements Runnable { @Override public void run() { //Time consuming operation for(int x = 0 ; x < 100 ; x ++){ //public static Thread currentThread() System.out.println(Thread.currentThread().getName()+":"+x); } } } public class ThreadDemo { public static void main(String[] args) { //You can assign instances of classes (create instances of classes) MyRunnable my = new MyRunnable() ; //Resource class: shared by multiple threads / / concrete class new concrete class //Create two thread class objects Thread t1 = new Thread(my,"Zhang Junjie") ; Thread t2 = new Thread(my,"Gao Yuanyuan") ; //Start threads separately t1.start(); t2.start(); } }
Static proxy
Static proxy
- Features: real role and proxy role must implement the same interface
- Real role: focus on your own functions
- Proxy role: complete the "enhancement" of the real role function
public class ThreadDemo { public static void main(String[] args) { //Interface polymorphism //Mary mary = new You() ; You mary = new You() ; mary.mary(); System.out.println("----------------------"); //Static agent: help yourself You to get married through the wedding company //Real role You you2 = new You() ; // MyRunnable WeddingCompany wc = new WeddingCompany(you2) ;// Thread class object wc.mary(); } } //An interface that defines an interface interface Mary{ void mary() ;//marry } //Self: real role class You implements Mary{ @Override public void mary() { System.out.println("Get married,Very happy..."); } } //Acting role: before you get married, the wedding company can arrange wedding threads for you. After you get married, you can eat happily class WeddingCompany implements Mary{ //Pass real characters as parameters private You you ; public WeddingCompany(You you){ this.you = you ; } @Override public void mary() { System.out.println("Set up the wedding scene for you..."); you.mary(); //Just focus on your own things! System.out.println("The wedding thread is arranged,Eat a banquet..."); } }
Use mode 2 to realize multi window ticket selling
- The second way can better reflect "resource sharing"
public class SellTicket implements Runnable { //Member variables; 100 tickets public static int tickests = 100 ; //Create a lock object: public Object obj = new Object() ; //t1,t2,t3 @Override public void run() { //Simulation ticket while(true){ //t1,t2,t3 //Solution: //Wrap the operations of multiple statements on shared data //synchronized (new Object()) {/ / lock object: three threads use their own locks //Must be the same lock object synchronized (obj){ //Analog network delay //judge if(tickests>0){//100>0 //t1 comes first and sleeps for 150 milliseconds. t1 has finished sleeping. Perform the following operations //t3 comes in first, sleeps for 150 milliseconds, and after t3 wakes up //t2 finally grabbed it and woke up try { Thread.sleep(100); //In milliseconds } catch (InterruptedException e) { e.printStackTrace(); } //Output window information System.out.println(Thread.currentThread().getName()+"The second is being sold"+(tickests--)+"Ticket"); } } public class SellTicketTest { public static void main(String[] args) { //Create resource class object SellTicket SellTicket st = new SellTicket() ; //Create three thread class objects Thread t1 = new Thread(st,"Window 1") ; Thread t2 = new Thread(st,"Window 2") ; Thread t3 = new Thread(st,"Window 3") ; //Start threads separately t1.start(); t2.start(); t3.start(); } }
Criteria for testing multithreading security issues
- 1) Whether it is a multi-threaded environment cannot be changed. Use multi-threaded implementation
- 2) Whether there is shared data (data of resource class: tickets ticket) must have shared data
- 3) Whether there are multiple statements to operate on shared data is the solution
Interview question (why are these methods of Thread wait / Thread wake not defined in the Thread class, but in the Object class?)
- wait() method / notify() method -- also known as "synchronization" - > wait for wake-up mechanism
- It is related to the lock object, which can be any java class object, ---- object (top-level parent class)
Interview question (what is synchronization method?)
- If the first sentence of the method body of a method is synchronization code block, you can extract the synchronized keyword on the method declaration, followed by the permission modifier synchronized. The permission modifier synchronized returns the value type method name (formal list) {/ / non static synchronization method business logic
public class SellTicket implements Runnable { //Define 100 tickets public static int tickets = 100 ; //Define a statistical variable int x = 0 ; public Object obj = new Object() ;//Lock object obj @Override public void run() { while(true){ if(x % 2 ==0){ // // synchronized (obj){ // synchronized (this) {/ / consistent with the lock object of the following non static synchronization method synchronized (SellTicket.class){ //It is consistent with the static synchronization method lock object below if(tickets>0){ //sleep try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"The second is being sold"+(tickets--)+"Ticket"); } } }else{ sellTicket() ; //Synchronization method //x%2!=0 /* synchronized (obj){ if(tickets>0){ //sleep try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"The "+ (tickets -- +" ticket ") is being sold; } }*/ } x ++ ; //x=1 } } //A ticket selling method was called // sellTicket() ; //Synchronization method // What are the lock objects of public synchronized void sellTicket() {//sellTicket? By default, they are non static. this is the address value reference of the current class object public static synchronized void sellTicket() { //Static synchronization method: lock object, related to class: bytecode file object of current class: class name class if(tickets>0){ //sleep try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"The second is being sold"+(tickets--)+"Ticket"); } } } public class ThreadDemo { public static void main(String[] args) { //Create resource class object SellTicket st = new SellTicket() ; //Create a thread class object and pass st as a parameter Thread t1 = new Thread(st,"Window 1") ; Thread t2 = new Thread(st,"Window 2") ; Thread t3 = new Thread(st,"Window 3") ; //Start thread t1.start(); t2.start(); t3.start(); } }
Deadlock (DieLock)
- Thread safety issues:
It can be solved by synchronizing methods or synchronizing code blocks, but deadlock may occur during execution - Deadlock problem:
(use the synchronization mechanism to solve thread safety) there is a situation of waiting for each other between threads! - Solution:
Communication between multiple threads: you must use a resource class object, not each thread using its own resource class object!
Use the idea of generator and consumer mode to solve the problem. The prerequisite is that the generator thread and consumer thread must operate on the same resource class object!
public class MyMonitor { //Two lock objects are provided public static final Object objA = new Object() ; public static final Object objB = new Object() ; } public class DieLock implements Runnable { private boolean flag ;//Tag value public DieLock(boolean flag){ this.flag = flag ; } @Override public void run() { //Judge tag value //t1 ---->DieLock(true) //t2 ---->DieLock(false) if(flag){ //t1 synchronized (MyMonitor.objA){ System.out.println("if ObjeA");//"if objA" synchronized (MyMonitor.objB){ System.out.println("if objB");// "if objB" } } }else{ //t2 synchronized (MyMonitor.objB){ System.out.println("else ObjB"); //else objB synchronized (MyMonitor.objA){ System.out.println("else objA"); //"else objA" } } } /** * t2 The thread got it first * else ObjB ---->Wait for the ObjA lock to release * if ObjeA ---->Wait for the ObjB lock to release * * t1 The thread preempted first * if ObjeA * else ObjB */ } } public class DieLockDemo { public static void main(String[] args) { //Create resource class object DieLock d1 = new DieLock(true) ; DieLock d2 = new DieLock(false) ; //Create objects in Thread Thread t1 = new Thread(d1) ; Thread t2 = new Thread(d2) ; //Start separately t1.start(); t2.start(); } }
Resolve deadlock issues (producer consumer mindset)
- 1)StuffBun package subclass properties
Contains the name of the bun
Size of steamed stuffed bun - 2) The producer resource class SetBun generates buns
- 3) Consumer resource class GetBun uses package
- 4) Threaddemo: mainuser thread
public class StuffBun { //Member variables are not privatized String name ;//Type of steamed stuffed bun (meat steamed stuffed bun, vegetable steamed stuffed bun) String bunType ;//Big steamed stuffed bun / small steamed stuffed bun } public class SetBun implements Runnable { //Declare this package subclass private StuffBun stu ; public SetBun(StuffBun stu){ this.stu = stu ; } //Define a statistical variable int x = 0 ; @Override public void run() { //Produce steamed stuffed bun /* StuffBun stu = new StuffBun() ; stu.name = "Meat bun "; stu.bunType = "Large type ";*/ //Continuously generate data while(true){ synchronized (stu){ if(x % 2 == 0){//t1 stu.name = "steamed meat bun" ; stu.bunType = "Big stuffed bun"; }else{ stu.name = "vegetable bun" ; stu.bunType = "Steamed stuffed bun" ; } } x ++ ; } } } public class GetBun implements Runnable { //Declare the variable stb of the package subclass private StuffBun stb ; public GetBun( StuffBun stb){ this.stb = stb ; } @Override public void run() { //Data to be used for simulation // StuffBun stb = new StuffBun() ; //Continuous use of data while(true){ synchronized (stb){ System.out.println(stb.name+"---"+stb.bunType); } } } } public class ThreadDemo { public static void main(String[] args) { //Create a package sub object StuffBun sbu = new StuffBun() ; //Same object //Create production resource class object SetBun sb = new SetBun(sbu) ; //Consumer resource class object GetBun gb = new GetBun(sbu) ; //Thread created object Thread t1 = new Thread(sb) ;//The producer thread in which the producer resource class resides Thread t2 = new Thread(gb) ;//The consumer thread where the consumer resource class is located t1.start(); t2.start(); } }
Resolve deadlock (wait()+notify())
public class StuffBun { //Member variables are not privatized private String name ;//Type of steamed stuffed bun (meat steamed stuffed bun, vegetable steamed stuffed bun) private String bunType ;//Big steamed stuffed bun / small steamed stuffed bun //Definition flag: indicates whether there is package sub data private boolean flag ; //The default is false and there is no data //Method for assigning value to package data public synchronized void set(String name,String bunType){ //The lock object is this: a non static synchronization method //If the current producer has no statements, it needs to wait for data generation if(this.flag){ //The lock object calls wait to send that message try { this.wait();//Release lock object } catch (InterruptedException e) { e.printStackTrace(); } } //assignment this.name = name ; this.bunType = bunType ; //If you have data now //Change signal this.flag = true ;//There are data classes //Notify (wake up) the consumer thread to use the data quickly this.notify(); //Wake up the other thread } //Providing method: obtain the data of steamed stuffed bun public synchronized void get(){ //Non static synchronization method: lock object this //If there is package data in the current consumption resource class, wait for the consumption data to be used first if(!this.flag){ //Waiting for data to be used up try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(this.name+"---"+this.bunType); //Change signal value //If the steamed stuffed bun is consumed this.flag = false ; //Wake up the other thread (producer resource class, don't wait, generate data) this.notify(); } } public class GetBun implements Runnable { //Declare the variable stb of the package subclass private StuffBun stu ; public GetBun( StuffBun stu){ this.stu = stu ; } @Override public void run() { //Data to be used for simulation // StuffBun stb = new StuffBun() ; //Continuous use of data while(true){ stu.get();//Get package data } } } public class SetBun implements Runnable { //Declare this package subclass private StuffBun stu ; public SetBun(StuffBun stu){ this.stu = stu ; } //Define a statistical variable int x = 0 ; @Override public void run() { //Produce steamed stuffed bun /* StuffBun stu = new StuffBun() ; stu.name = "Meat bun "; stu.bunType = "Large type ";*/ //Continuously generate data while(true){ if(x % 2 == 0){//t1 //stu.name = "meat buns"; //stu.bunType = "big steamed stuffed bun"; stu.set("steamed meat bun","Big stuffed bun"); }else{ //stu.name = "steamed stuffed bun"; //stu.bunType = "small steamed stuffed bun"; stu.set("vegetable bun","Steamed stuffed bun"); } x ++ ; } } } public class ThreadDemo { public static void main(String[] args) { //Create a package sub object StuffBun sbu = new StuffBun() ; //Same object //Create production resource class object SetBun sb = new SetBun(sbu) ; //Consumer resource class object GetBun gb = new GetBun(sbu) ; //Thread created object Thread t1 = new Thread(sb) ;//The producer thread in which the producer resource class resides Thread t2 = new Thread(gb) ;//The consumer thread where the consumer resource class is located t1.start(); t2.start(); } }
Lock
Method name | Method meaning |
---|---|
void unlock() | Attempt to release lock |
void lock() | Acquire lock |
public class SellTicket implements Runnable { //Define 100 tickets private static int tickets = 100 ; //Create a lock object Lock lock = new ReentrantLock() ; @Override public void run() { //Simulation one has only one ticket while(true){ //Get lock through lock object -- > lock.lock(); //try... catch... Finally: exception caught //Use try finally try{ //judge if(tickets>0){ //Sleep for 100 milliseconds try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"The second is being sold"+(tickets--)+"Ticket"); }else{ break ; } }finally { //Release lock lock.unlock(); } } } public class LockDemo { public static void main(String[] args) { //Create shared resource class object SellTicket st = new SellTicket() ; //Create three thread class objects Thread t1 = new Thread(st,"Window 1") ; Thread t2 = new Thread(st,"Window 2") ; Thread t3 = new Thread(st,"Window 3") ; //Start thread t1.start(); t2.start(); t3.start(); } }
ThreadGroup
- A thread group represents a group of threads. In addition, thread groups can include other thread groups
Thread group member method
Thread group member method name | Method meaning |
---|---|
public final ThreadGroup getThreadGroup() | Get thread group |
public Thread(ThreadGroup group, Runnable target) | Set the default thread group name for the thread |
public final String getName() | Gets the default thread group name |
public class MyThread implements Runnable { @Override public void run() { for(int x = 0 ;x < 100 ; x ++){ System.out.println(Thread.currentThread().getName()+":"+x); } } } public class ThreadGroupDemo { public static void main(String[] args) { //The jvm calls the main method // method1(); method2() ; } //Set a new thread group name private static void method2() { //Create a thread group object -- set the thread group name at the same time ThreadGroup tg = new ThreadGroup("myMain") ; //Create two thread objects MyThread my = new MyThread() ; Thread t1 = new Thread(tg,my) ; Thread t2 = new Thread(tg,my) ; //Get the thread group object and the thread group name at the same time String name1 = t1.getThreadGroup().getName(); String name2 = t2.getThreadGroup().getName(); System.out.println(name1+"---"+name2); } private static void method1() { //Create two threads MyThread my = new MyThread() ; Thread t1 = new Thread(my) ; Thread t2 = new Thread(my) ; ThreadGroup tg1 = t1.getThreadGroup(); ThreadGroup tg2 = t2.getThreadGroup(); String name1 = tg1.getName(); String name2 = tg2.getName(); System.out.println(name1+"---"+name2); //The default thread group name is main } }
Thread group construction method
- Thread group: all threads can be added to a group for easy management. After the thread is started and terminated, this thread object will not be reused in memory
Constructor name | Construction method meaning |
---|---|
public ThreadGroup(String name) {} |
Thread pool
- Thread pool belongs to the "pooling" technology -- -- > similar to database connection pool (DBCP, C3PO, Druid (born for monitoring))
- characteristic:
Create a fixed number of reusable threads in memory. The current thread terminates after execution and will not be recycled. Return to the thread pool again and wait for the next utilization! - Disadvantages: high maintenance cost
ExecutorService
Method name | Method meaning |
---|---|
public static ExecutorService newFixedThreadPool(int nThreads) | Create a fixed number of reusable threads, and the return value is the thread pool object |
Future submit(Callable task) | Submit the value to return the task for execution, and return the Future representing the pending results of the task. |
Future<?> submit(Runnable task) | Return value of submit: the result of asynchronous calculation. If no calculation is performed, there is no need to return the result! |
public class MyCallable implements Callable { @Override public Object call() throws Exception { for(int x = 0 ; x < 100 ; x++){ System.out.println(Thread.currentThread().getName()+":"+x); } return null; } } public class MyRunnable implements Runnable { @Override public void run() { for(int x = 0 ; x < 100 ; x ++){ System.out.println(Thread.currentThread().getName()+":"+x); } } } public class ThreadPoolDemo { public static void main(String[] args) { //Create a thread pool object through the factory class ExecutorService threadPool = Executors.newFixedThreadPool(2); //Commit asynchronous method //MyRunnable: print the data between the value of x and 0-99. No result needs to be returned // threadPool.submit(new MyRunnable()) ; // threadPool.submit(new MyRunnable()) ; // <T> Future<T> submit(Callable<T> task) //Callable: submit asynchronous calculation - the callable call needs to be rewritten to calculate the result; If there is no result, you do not need to return it directly in the call threadPool.submit(new MyCallable()) ; threadPool.submit(new MyCallable()) ; //void shutdown() closes the thread pool threadPool.shutdown(); } }
Design principles
- Opening and closing principle:
Close the modification of existing code and open it to extension code - Interface separation principle
A function is defined in an interface. Interfaces and interfaces are independent and cannot affect each other - Richter substitution principle:
Any place where a parent class appears can be replaced by a child class!
Design pattern
- All 23 design patterns need to follow the principle of "low coupling, high cohesion"
- Creation type: creation of objects (most used)
- Simple factory: --- called static factory method pattern
- Advantages: using polymorphism to create subclass objects can flexibly create objects (static functions provided)
- Disadvantages: a large amount of code. Once a new type is added, the static function of the factory class needs to be changed
- Structural type: the composition of the whole structure
- Behavioral: functional
Animals (parent)
public class Animal { public void eat(){ System.out.println("eat"); } public void sleep(){ System.out.println("sleep"); } }
The xxxFactory factory class is specifically responsible for creating instances of a certain type
public class AnimalFactory { //Provide a static method //Create a dog /*public static Dog creatDog(){ return new Dog() ; } //Create a cat public static Cat createCat(){ return new Cat() ; }*/ //Polymorphic mode public static Animal createAnimal(String type){ if("cat".equals(type)){ return new Cat() ; }else if("dog" .equals(type)){ return new Dog() ; }else if("pig".equals(type)){ return new Pig() ; } return null ; } }
Cats, dogs, pigs (subclasses)
public class Cat extends Animal { @Override public void eat() { System.out.println("Cats eat fish..."); } @Override public void sleep() { System.out.println("The cat sleeps on its stomach"); } } public class Dog extends Animal { @Override public void eat() { System.out.println("Dogs eat bones"); } @Override public void sleep() { System.out.println("The dog lies asleep"); } } public class Pig extends Animal { @Override public void eat() { System.out.println("Pigs eat cabbage"); } @Override public void sleep() { System.out.println("The pig sleeps on its side..."); } }
Test class
public class PatternDemo1 { public static void main(String[] args) { //No design patterns are provided //Create a concrete class object //Use polymorphism //Cat c = new Cat() ; Animal a = new Cat() ; a.eat(); a.sleep(); a = new Dog() ; a.eat(); a.sleep(); System.out.println("----------------------------------------------"); //Use simple factory (static factory method) mode /* Dog dog = AnimalFactory.creatDog(); dog.eat(); dog.sleep(); Cat cat = AnimalFactory.createCat(); cat.eat(); cat.sleep();*/ //Continue to optimize: with the continuous increase of types, the code of factory class is constantly modified (opening and closing principle) //Object modification is closed and open to extensions //Using polymorphism to complete Animal animal = AnimalFactory.createAnimal("cat"); animal.eat(); animal.sleep(); animal = AnimalFactory.createAnimal("dog"); animal.eat(); animal.sleep(); animal = AnimalFactory.createAnimal("pig"); animal.eat(); animal.sleep(); animal = AnimalFactory.createAnimal("monkey"); if(animal!=null){ animal.eat(); animal.sleep(); }else{ System.out.println("No instance creation for this animal was provided"); } } }
Join
Method name | Method meaning |
---|---|
public final void join() throws InterruptedException | Wait for the thread to terminate! |
- The underlying thread safety dependent method join(0): always wait (the current execution is finished!)
- It also depends on wait(long time)
Consider safety issues: - Three threads - priority is the default (5)
- Set the join(): who preempts the three threads and who executes them first
public class JoinThread extends Thread{ @Override public void run() { for(int x =0 ; x < 100 ; x ++){ System.out.println(getName()+":"+x); } } } public class ThreadJoinDemo { public static void main(String[] args) { //Create three threads JoinThread jt1 = new JoinThread() ; JoinThread jt2 = new JoinThread() ; JoinThread jt3 = new JoinThread() ; //Set thread name jt1.setName("Li Yuan") ; jt2.setName("Shi Min Li") ; jt3.setName("Li Yuanba") ; //Start thread jt1.start(); //jt1 calls join try { jt1.join(); } catch (InterruptedException e) { e.printStackTrace(); } jt2.start(); try{ jt2.join(); }catch(InterruptedException e){ e.printStackTrace(); } jt3.start(); } }
Yield
Method name | Method meaning |
---|---|
public static void yield() | Pause the currently executing thread and execute the other thread |
public class YieldThread extends Thread{ //yt1/yt2 @Override public void run() { for(int x = 0 ; x <100 ; x ++){ System.out.println(getName()+":"+x); Thread.yield(); //Pause the current thread and execute the other thread } } } public class ThreadYieldDemo { public static void main(String[] args) { //Create two thread objects YieldThread yt1 = new YieldThread() ; YieldThread yt2 = new YieldThread() ; //Set name yt1.setName("Gao Yuanyuan") ; yt2.setName("You Ting Zhao") ; //Start thread yt1.start(); yt2.start(); } }
Daemon
Method name | Method meaning |
---|---|
public final void setDaemon(boolean on) | If the parameter is true, it indicates that the current thread is marked as a daemon thread. If all running threads are daemon threads, the jvm will exit automatically |
- If all running threads are daemon threads and the jvm exits, the running thread will not stop immediately!
public class ThreadDaemon extends Thread { @Override public void run() { for (int x = 0 ; x < 100; x ++){ System.out.println(getName()+":"+x); } } } public class ThreadDaemonDemo { public static void main(String[] args) { //Create two threads ThreadDaemon td1 = new ThreadDaemon() ; ThreadDaemon td2 = new ThreadDaemon() ; //Set name td1.setName("Fei Zhang"); td2.setName("Guan Yu"); //Set as daemon thread td1.setDaemon(true) ; td2.setDaemon(true) ; //Start thread td1.start(); td2.start(); // public static Thread currentThread(): get the reference of the running thread execution object Thread.currentThread().setName("Liu Bei"); //Provide for loop: for(int x = 0 ; x < 5 ; x ++){ System.out.println(Thread.currentThread().getName()+":"+x); } } }