Several methods of multithreading
1. Inherit Threa class
//Thread common methods Thread t=new Thread("kk");//Name the new thread System.out.println(t.getName());//Gets the name of the thread Thread.currentThread( ).getName()//Call the name of the running thread by getting the current thread object Thread.sleep(1000)//Hibernates the current thread in milliseconds new Thread(){ @Overridr public void run(){ //Code to execute } }.start();//Start the thread internally
//An implementation of multithreading package basic; public class Test { public static void main(String[] args) { ThreadTest test1=new ThreadTest("jack"); ThreadTest test2=new ThreadTest("ank");//Set thread name ThreadTest test3=new ThreadTest("dack"); test1.start(); test2.start(); test3.start(); } } class ThreadTest extends Thread{ public ThreadTest(String string) { super(string); } @Override public void run() { int i=0; while(i<5){ i++; //To get the name of the current thread set, you need to add a parameter structure, which can be obtained directly by using the getName method System.out.println(getName()+"="+i); /*The business code must be written in run()*/ } } }
2. Implement Rundble interface
package test; public class Teststs { public static void main(String[] args) throws InterruptedException { A a=new A(); Thread thread=new Thread(a,"jack"); Thread thread2=new Thread(a,"lucy"); thread.start(); thread2.start(); } } class A implements Runnable{ @Override public void run() { int i=0; while (i<9){ i++; System.out.println(Thread.currentThread().getName()+i); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Synchronous lock
Keyword: synchronized
- Premise 1: synchronization requires two or more threads (multithreading safety does not need to be considered for a single thread)
- Premise 2: multiple threads must use the same lock (other people can see the lock after I lock it, otherwise my lock can't lock others, so there will be no locking effect)
synchronized (lock object){
Code that needs to be synchronized (i.e. multiple statements that operate and share data that may have problems);
}
package test; public class Teststs { public static void main(String[] args) throws InterruptedException { A a=new A("jack"); A b=new A("lucy"); a.start(); b.start(); } } class A extends Thread { static int i = 100;//Static resources are globally shared and unique. Thread safety problems may occur in multithreaded calls and need to be locked public A(String name) { super(name); } @Override public void run() { while (true) { //In case of inheritance, it is better to use "class name. Class" for the lock object, otherwise when creating multiple objects of custom thread class, the uniqueness of the lock cannot be guaranteed synchronized (A.class) { if (i > 0) { try { i--; System.out.println(Thread.currentThread().getName() + i); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } if(i==0) break; } } } }
//Implement the Runable interface, and the effect is the same as above package test; public class Teststs { public static void main(String[] args) throws InterruptedException { A aa =new A(); Thread a=new Thread(aa,"jack"); Thread b=new Thread(aa,"lucy"); a.start(); b.start(); } } class A implements Runnable{ static int i = 100; @Override public void run() { while (true) { synchronized (A.class) { if (i > 0) { try { i--; System.out.println(Thread.currentThread().getName() + i); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } if(i==0) break; } } } }
3. Thread pool: ExecutorService/Executors
ExecutorService: a pool used to store threads. The pool is used to manage the tasks of creating / starting / closing threads
execute(Runnable task object) drops the task to the thread pool
Executors is a tool class that assists in creating thread pools
newFixedThreadPool(int nThreads) a thread pool of up to n threads
newCachedThreadPool() has enough threads so that the task does not have to wait
newSingleThreadExecutor() has only one thread pool
package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Teststs { public static void main(String[] args) throws InterruptedException { A a =new A(); ExecutorService pool= Executors.newFixedThreadPool(5);//Create a thread pool with a length of 5 for(int i =0;i<5;i++){ pool.execute(a);//Loop creates a thread and executes it } } } class A implements Runnable{//Business code static int i = 55; @Override public void run(){ while (true) { synchronized (A.class) { if (i > 0) { try { i--; System.out.println(Thread.currentThread().getName() + " " + i); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } if(i==0) break; } } } }
//Read write lock mechanism package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Teststs { public static void main(String[] args) throws InterruptedException { A a =new A(); ExecutorService pool= Executors.newFixedThreadPool(5); for(int i =0;i<5;i++){ pool.execute(a); } } } class A implements Runnable{ static int i = 55; ReentrantReadWriteLock lock=new ReentrantReadWriteLock();//It can also be locked with a read-write lock @Override public void run(){ while (true) { lock.writeLock().lock(); try { if (i > 0) { i--; System.out.println(Thread.currentThread().getName() + " " + i); Thread.sleep(14); } if(i==0) break; } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.writeLock().unlock();//The read-write lock needs to be manually released } } } }
synchronized mutex (pessimistic lock, guilt assumption)
ReentrantLock exclusive lock (pessimistic lock, guilty assumption): only one thread of exclusive lock can access at the same time. In fact, exclusive lock is a relatively conservative lock strategy. In this case, any "read / read", "read / write" or "write / write" can be used Operations cannot occur at the same time, which reduces the throughput to a certain extent. However, there is no data competition between read operations
ReentrantReadWriteLock read / write lock (optimistic lock, innocence assumption): the read / write lock is divided into read lock and write lock. When there is no write lock, the read lock can be held by multiple threads at the same time, and the write lock is exclusive.
Read lock and write lock are separated to improve program performance. Read / write lock is mainly used in scenarios with more reads and less writes.
Read write locks allow a higher level of concurrent access to shared data than mutexes. Although only one thread (writer thread) can modify shared data at a time, in many cases, any number of threads can read shared data at the same time (reader thread). Theoretically, compared with mutually exclusive locking, the concurrency enhancement allowed by using read-write lock will bring greater performance improvement.
Singleton design pattern
//Lazy style package test; public class Teststs { public static void main(String[] args) { Object o1=A.getA(); Object o2=A.getA(); System.out.println(o1==o2);//The result is true, which proves that the two are the same object } } class A { private A(){};//Privatize the construction method, so that the outside world cannot create this kind of object at will private static A a; //Create a static object of this class, but do not instantiate it private static Object o=new Object(); public static A getA(){//Provide a unique method for obtaining this class of objects synchronized (o){//Adding a synchronization lock ensures that only one thread can call this class of objects at a time if(a==null){ a=new A();//Instantiate the object and return it to the object calling the method } return a; } } } Hungry Chinese style is in the object class( A)First define a private object of this class directly, and then provide a static method to call
annotation
Notes are divided into three categories:
- JDK's own annotation
- Meta annotation
- Custom annotation
There are five JDK annotations:
@Override: used to identify the override method (common)
@The Deprecated flag indicates that this method is outdated, but I will use it. Don't prompt me to expire
@SuppressWarnings("deprecation") ignore warnings
@SafeVarargs jdk1.7. Heap pollution occurs, which is not commonly used
@FunctionallInterface jdk1.8 appears. It is not commonly used in conjunction with functional programming ramda expression
Meta annotation: five annotations used to describe annotations:
@Where are Target annotations used: on classes, methods, properties, etc. (commonly used)
@Life cycle of Retention annotation: in source file, bytecode file and running (common)
@Inherited allows child annotation inheritance
@The javadoc generated by Documented contains annotations, which are not commonly used
@Repeatable annotation is a repeatable type annotation, which can be used multiple times in the same place and is not commonly used
@ Target ElementType: describes where the annotation exists:
ElementType.TYPE applies to the elements of the class
ElementType.METHOD is applied at the method level
ElementType.FIELD applies to fields or attributes (member variables)
ElementType.ANNOTATION_TYPE applies to annotation types
ElementType.CONSTRUCTOR applies to constructors
ElementType.LOCAL_VARIABLE applies to local variables
ElementType.PACKAGE applies to package declarations
ElementType.PARAMETER the parameter applied to the method
@ Retention RetentionPolicy: defines how long a custom annotation is retained
SOURCE is valid in the SOURCE file (i.e. SOURCE file retention)
class is valid in the class file (i.e. class is reserved)
RUNTIME is valid at RUNTIME (i.e. RUNTIME retention)
package test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class Teststs { public static void main(String[] args) throws InterruptedException { new Teststs().name(new Teststs().name); } @A String name; @A public void name(String name){ System.out.println(name); } } @Target({ElementType.METHOD,ElementType.FIELD,ElementType.ANNOTATION_TYPE,ElementType.TYPE_USE})//Scope of annotation @Retention(RetentionPolicy.CLASS)//Save time of annotation @interface A {//Mark this is an annotation String name="Cannot be empty"; String age="Cannot be empty"; }