Learning Java multithreading is enough (good article is worth sharing!)

Multi thread learning

1. Multithreading_ concept

Multithreading, in short, is multitasking.
Inter method call: an ordinary method call is a closed path from where to where.
Multithreading: opens up multiple paths.

2. Multithreading_ Inherit Thread

There are three ways to create threads:

  • (1) Inherit Thread
  • (2) Implement Runnable interface
  • (3) Implement Callable interface (just understand)
    Key points: less inheritance and more implementation

Do you know what the three high problem is?
High availability, high performance and high concurrency

Knock the code and you'll know.

public class Test1 extends Thread {
	//Create access port
	@Override
	public void run() {
		for(int i=0;i<20;i++) {
			System.out.println("Knock code");
		}
	}
	public static void main(String[] args) {
		/*
		 * Thread creation mode 1:
		 * Inherit Thread + override run
		 */
		//Create subclass objects
		Test1 st=new Test1();
		//start-up
		st.start();  //Immediate operation is not guaranteed, cpu calls
//		st.run(); // Method call
		for(int i=0;i<20;i++) {
			System.out.println("I am learning");
		}
	}
}

3. Multithreading_ Picture download

Know that using multithreading to download online pictures is also a necessary skill!

/*
 * Download pictures
 */
public class Test2 {
	public void download(String url,String name) {
		try {
			FileUtils.copyURLToFile(new URL(url),new File(name));
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
			System.out.println("illegal url!");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Download failed!");
		}
	}
}
public class TDownloader extends Thread {
	private String url;  //Remote path
	private String name;  //Storage path
	
	public TDownloader(String url, String name) {
		this.url = url;
		this.name = name;
	}
	@Override
	public void run() {
		Test2 wd=new Test2();
		wd.download(url,name);
		System.out.println(name);
	}
	public static void main(String[] args) {
		TDownloader td1=new TDownloader("Picture URL","p1.jpg");
		TDownloader td2=new TDownloader("Picture URL","p2.jpg");
		TDownloader td3=new TDownloader("Picture URL","p3.jpg");
		
		//Start three threads
		td1.start();
		td2.start();
		td3.start();
	}
}

Try it after you learn

4. Multithreading_ Implement Runnable

What should you think of when you see the realization?
Yes, it's the interface!

/*
 * Implement Runnable
 */
public class Test3 implements Runnable {
	/*
	 * Thread access point
	 */
	@Override
	public void run() {
		for(int i=0;i<20;i++) {
			System.out.println("Knock code");
		}
	}
	public static void main(String[] args) {
		new Thread(new Test3()).start();
		for(int i=0;i<20;i++) {
			System.out.println("Listening to music");
		}
	}
}

5. Multithreading_ Ticket grabbing_ Tortoise and rabbit race

It's no use learning multithreading without showing its role. This time, we'll implement it with the most familiar turtle and rabbit race and ticket grabbing problem.

1) Simulated ticket purchase

public class Test4 implements Runnable{
	//Number of votes
	private int tickets=99;
	@Override
	public void run() {
		while(true) {
			if(tickets<0) {
				break;
			}
			System.out.println(Thread.currentThread().getName()+"-->"+tickets--);
		}
	}
	public static void main(String[] args) {
		//A resource
		Test4 web1=new Test4();
		//Multiple agents
		new Thread(web1,"programmer").start();
		new Thread(web1,"Code farmer").start();
		new Thread(web1,"Development Engineer").start();
	}
}

2) Simulated tortoise rabbit race

/*
 * Simulated tortoise rabbit race
 */
public class Test5 implements Runnable{
	private static String winner;  //winner
	@Override
	public void run() {
		for(int steps=1;steps<=100;steps++) {
			//Simulated rest
			if(Thread.currentThread().getName().equals("rabbbit")&&steps%100==0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName()+"-->"+steps);
			//Is the game over
			boolean flag=gameOver(steps);
			if(flag) {
				break;
			}
			
		}
	}
	private boolean gameOver(int steps) {
		if(winner!=null) {  //There is a winner
			return true;
		}else {
			if(steps==100) {
				winner=Thread.currentThread().getName();
				System.out.println("winner ==>"+winner);
				return true;
			}
		}
		return false;
	}
	public static void main(String[] args) {
		Test5  racer=new Test5();
		new Thread(racer,"tortoise").start();
		new Thread(racer,"rabbit").start();
	}
}

6. Multithreading_ Learn about Callable

Steps to implement Callable:

  • 1. Create target object: CDownloader cd=new CDownloader("picture address", "baidu.png") / / CDownloader class name
  • 2. Create execution service: executorservice ser = executors newFixedThreadPool(1);
  • 3. Submit execution: future res = Ser submit(cd1);
  • 4. Get result: boolean r1=res.get();
  • 5. Shut down the service: Ser shutdownNow();

7. Multithreading_ Static agent design pattern

/*
 * Static proxy:
 * Interface:
 * 1,Real role
 * 2,delegable role
 */
public class Test6 {
	public static void main(String[] args) {
		new WeddingCompany(new You()).happy();
		//New thread (thread object). start()
	}
}
interface Marry{
	void happy();
}
class You implements Marry{

	@Override
	public void happy() {
		System.out.println("You and ");
	}
}
//delegable role
class WeddingCompany implements Marry{
	//Real role
	private Marry target;
	public WeddingCompany(Marry target) {
		this.target=target;
	}
	@Override
	public void happy() {
		ready();
		this.target.happy();
		after();
	}
	private void ready() {
		System.out.println("arrangement");
	}
	private void after() {
		System.out.println("start");
	}
}

8. Multithreading_ Lambada_ Simplify threads

public class TestLambda {
	//Static inner class
	static class Test implements Runnable{
		public void run() {
			for(int i=0;i<20;i++) {
				System.out.println("Knock code");
			}
		}
	}
	public static void main(String[] args) {
		//Static inner class
//		new Thread(new Test()).start();
		//Local inner class
		class Test2 implements Runnable{
			public void run() {
				for(int i=0;i<20;i++) {
					System.out.println("Knock code");
				}
			}
		}
		//Local inner class
//		new Thread(new Test2()).start();
		//Anonymous Inner Class 
		new Thread(new Runnable() {
			public void run() {
				for(int i=0;i<20;i++) {
					System.out.println("Knock code");
				}
			}
		}).start();
		//jdk8 simplified lambda is used to simplify simple threads. Only one method can be deduced
		new Thread(()->{
			for(int i=0;i<20;i++) {
				System.out.println("Knock code");
			}
		}).start();
		
	}
}

Warm tip: lambda: you can take parameters, omit curly braces for one sentence, and omit type names (multiple parameters are OK)

9. Multithreading_ termination

public class Test7 implements Runnable{
	//Add a sign to mark whether the layer body can run
	private boolean flag=true;
	private String name;
	public Test7(String name) {
		this.name=name;
	}
	
	@Override
	public void run() {
		int i=0;
		//Association flag true -- > Run false -- > stop
		while(flag) {
			System.out.println(name+"-->"+i++);
		}
	}
	//3. External provision method change sign
	public void Test7() {
		this.flag=false;
	}
	public static void main(String[] args) {
		Test7 tt=new Test7("xiaoha");
		new Thread(tt).start();
		for(int i=0;i<99;i++) {
			if(i==88) {
				tt.Test7();
				System.out.println("game Over");
			}
			System.out.println("main-->"+i);
		}
		
	}
}

10. Multithreading_ Pause sleep

Case: 12306 ticket purchase, tortoise and rabbit race
Do it yourself

11. Multithreading_ yield

Knowledge point: yield the thread to pause. The thread directly enters the ready state, not the blocking state

public class TestYield {
	public static void main(String[] args) {
		MyYield my=new MyYield();
		new Thread(my,"a").start();
		new Thread(my,"b").start();
	}
}
class MyYield implements Runnable{

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+"-->start");;
		Thread.yield();
		System.out.println(Thread.currentThread().getName()+"-->end");;
	}
	
}

12. Multithreading_ Jump the queue join

Knowledge point: join: merge thread queue thread

public class TestJoin {
	public static void main(String[] args) {
		System.out.println("The story of father and son buying cigarettes");
		new Thread(new Father()).start();
	}
}
class Father extends Thread{
	public void run() {
		System.out.println("I wanted to smoke, but I didn't find it");
		System.out.println("Let my son buy cigarettes");
		Thread t=new Thread(new Son());
		t.start();
		try {
			t.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Dad took the cigarette and gave him the change");
	}
}
class Son extends Thread{
	public void run() {
		System.out.println("Take dad's money..");
		System.out.println("There was a game console on the side of the road. I played it for a while");
		for(int i=0;i<10;i++) {
			System.out.println(i+"Seconds have passed");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("Hurry to buy cigarettes..");
		System.out.println("He went home with a pack of cigarettes in his hand..");
	}
}

13. Multithreading_ Deep observation state

Knowledge points: blocking status: sleep, join, wait, read, write

public class AllState {
	public static void main(String[] args) {
		Thread tt=new Thread(()->{
			for(int i=0;i<5;i++) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(".....");
		});
		//Observation state
		State state=tt.getState();
		System.out.println(state);  //NEW
		
		tt.start();
		state=tt.getState();  //RUNNING
		while(state!=Thread.State.TERMINATED) {
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			state=tt.getState();
			System.out.println(state);  //TIMED_WAITING
		}
	}
}

14. Multithreading_ priority

  • 1,NORM_PRIORITY
  • 2,MIN_PRIORITY
  • 3,MAX_PRIORITY
  • Probability does not represent absolute order
public class TestPriority {
	public static void main(String[] args) {
		System.out.println(Thread.currentThread().getPriority());
		MyPriority mp=new MyPriority();
		Thread t1=new Thread(mp,"Double happiness");
		Thread t2=new Thread(mp,"Warrior ");
		Thread t3=new Thread(mp,"NIKE");
		Thread t4=new Thread(mp,"Li Ning");
		t1.setPriority(Thread.NORM_PRIORITY);
		t2.setPriority(Thread.MIN_PRIORITY);
		t3.setPriority(Thread.MAX_PRIORITY);
		t4.setPriority(Thread.MIN_PRIORITY);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}
class MyPriority implements Runnable {

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
	}
	
}

15. Multithreading_ Daemon thread

Knowledge point: guard thread: it serves user threads; The jvm stops without waiting for the daemon thread to finish executing

public class Test8 {
	public static void main(String[] args) {
		God god=new God();
		Ni you=new Ni();
//		new Thread(god).start();
		Thread t=new Thread(god);
		t.setDaemon(true);  //Adjust user thread to daemon
		t.start();
		new Thread(you).start();
	}
}
class Ni implements  Runnable{
	@Override
	public void run() {
		for(int i=0;i<=365*100;i++) {
			System.out.println("happy life");
		}
		System.out.println("hahaah");
	}
}
class God implements Runnable{
	@Override
	public void run() {
		for(;true;) {
			System.out.println("belss you");
		}
	}
}

16. Multithreading_ Basic information_ Net red thinking

  • isAlive: is the thread still alive
  • Thread.currentThread(): current thread
  • setName, getName: Agent Name
public class Test9 {
	public static void main(String[] args) {
		System.out.println(Thread.currentThread().isAlive());  //-->true
		
		//Setting Name: real role + proxy role
		MyInfo info=new MyInfo("audi");
		Thread t=new Thread(info);
		t.setName("Benz");
		t.start();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(t.isAlive());  //-->false
		
	}
}
class MyInfo implements Runnable{
	private String name;
	public MyInfo(String name) {
		this.name=name;
	}
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+name);
	}
}

17. Multithreading_ Concurrent_ Asynchronous_ Three classic cases

  • Thread unsafe: data is negative and the same
  • Thread unsafe: withdraw money
public class UnsafeTest1 {
	public static void main(String[] args) {
		//account
		Account account=new Account(100,"Wedding gift");;
		Drawing you=new Drawing(account,80,"Lovely you");
		Drawing wife=new Drawing(account,90,"happy");
		you.start();
		wife.start();
		
	}
}
//account
class Account{
	int money;  //amount of money
	String name; //name
	public Account(int money,String name) {
		this.money=money;
		this.name=name;
	}
	
}
//Simulated withdrawal
class Drawing extends Thread{
	Account account;  //Withdrawal account
	int drawingMoney; //Amount of money obtained
	int drawingTotal; //Get total
	int packetTotal;  //Total number of pockets
	public Drawing(Account account, int drawingMoney,String name) {
		super(name);
		this.account = account;
		this.drawingMoney = drawingMoney;
	}
	@Override
	public void run() {
		if(account.money-drawingMoney<0){
			return ;
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		account.money-=drawingMoney;
		packetTotal+=drawingMoney;
		System.out.println(this.getName()+"-->"+"The balance of the account is:"+account.money);
		System.out.println(this.getName()+"-->"+"The money in the pocket is:"+packetTotal);
	}
	
}

18. Multithreading_ Concurrent_ Synchronization_ Queues and locks

  • Thread safety: ensure the correctness and efficiency of data during concurrency
  • synchronize

19. Multithreading_ Concurrent_ Synchronization_ synchronized synchronization block

  • synchronized(): lock the correct object
  • When manipulating containers and objects

20. Multithreading_ Concurrent_ Synchronization_ performance analysis

  • Thread is unsafe. The range is too small to lock
  • Lock in a reasonable range as much as possible

21. Multithreading_ Concurrent_ Synchronization_ Happy cinema

 public class TestSyn {
	public static void main(String[] args) {
		Cinema c=new Cinema(20,"Specific height");
		new Thread(new Customer(c,3),"xiaoda").start();
		new Thread(new Customer(c,2),"xiaoha").start();
	}
}
//customer
class Customer implements Runnable{
	Cinema cinema;
	int seat;
	
	public Customer(Cinema cinema, int seat) {
		super();
		this.cinema = cinema;
		this.seat = seat;
	}
	
	@Override
	public void run() {
		synchronized (cinema) {
			boolean flag=cinema.bookTickets(seat);
			if(flag) {
				System.out.println("Ticket issued successfully"+Thread.currentThread().getName()+"--->Location is"+seat);
			}else {
				System.out.println("Ticket issuing failed"+Thread.currentThread().getName()+"--->Insufficient position");
			}
		}
		
		
	}
	
}
//cinema
class Cinema{
	int available;  //Available locations
	String name;  //name
	public Cinema(int available, String name) {
		super();
		this.available = available;
		this.name = name;
	}
	//Ticket purchase
	public boolean bookTickets(int seat) {
		System.out.println("Available locations:"+available);
		if(seat>available) {
			return false;
		};
		available-=seat;
		return true; 
	}
}

22. Multithreading_ Concurrent_ Deadlock_ Generation and solution

  • Deadlock: too many synchronizations may cause mutual non release of resources
  • Thus, they wait for each other, which usually occurs when they hold locks of multiple objects in synchronization
  • Avoid: do not hold multiple object locks in the same code block at the same time
public class TestSyn{
	public static void main(String[] args) {
		MakeUp g1=new MakeUp(1,"qiqi");
		MakeUp g2=new MakeUp(2,"gaga");
		g1.start();
		g2.start();
	}
}
//Lipstick
class LipStick{
	
}
//mirror
class Mirror{
	
}
//Make up
class MakeUp extends Thread{
	static LipStick lipstick=new LipStick();
	static Mirror mirror=new Mirror();
	//choice
	int choice;
	//name
	String name;
	public MakeUp(int choice, String name) {
		super();
		this.choice = choice;
		this.name = name;
	}
	@Override
	public void run() {
		//Make up
		makeup();
	}
	//Holding each other's object lock -- > may cause deadlock
	private void makeup() {
		if(choice==0) {
			synchronized (lipstick) {  //Get lipstick lock
				System.out.println(this.name+"Get lipstick");
				//I want to have a mirror in 1 second
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
//				synchronized (mirror) {
//					System.out.println(this.name + "get a mirror");
//				}
			}	
			synchronized (mirror) {
				System.out.println(this.name+"Get mirror");
			}
		}else {
			synchronized (mirror) {
				System.out.println(this.name+"Get mirror");
				//Want to have lipstick in 2 seconds
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
//				synchronized (lipstick) {/ / get the lock of lipstick
//					System.out.println(this.name + "get lipstick");
//				}	
			}
			synchronized (lipstick) {  //Get lipstick lock
				System.out.println(this.name+"Get lipstick");
			}	
		}
	}
}

23. Multithreading_ Concurrent collaboration_ Producer consumer model

Solution 1: concurrent collaboration model > management method
Producer: the module responsible for production data. (the modules here may be: methods, objects, threads and processes)
Consumer: the module responsible for processing data. (the modules here may be: methods, objects, threads and processes)
Buffer: consumers cannot directly use the producer's data. There is a buffer between them

Solution 2: concurrent collaboration model - > semaphore method

24. Multithreading_ Concurrent collaboration_ Pipe program method

  • Collaboration model: producer consumer - > pipe process method
  • Create a buffer
public class TestCusPro {
	public static void main(String[] args) {
		SynContainer container=new SynContainer();
		new Producer(container).start();
		new Customer(container).start();
		
	}
}
//producer
class Producer extends Thread{
	SynContainer container;
	public Producer(SynContainer container) {
		this.container=container;
	}
	public void run() {
		//production
		for(int i=0;i<100;i++){
			System.out.println("production"+i+"Items");
			container.push(new Goods(i));
		}
		
	}
}
//consumer
class Customer extends Thread{
	SynContainer container;
	public Customer(SynContainer container) {
		this.container=container;
	}
	public void run() {
		//consumption
		for(int i=0;i<100;i++) {  //Change 1000 to 100, or you'll be waiting
			System.out.println("consumption"+container.pop().id+"Items");
			
		}
	}
}
//buffer
class SynContainer{
	Goods[] goods=new Goods[10]; //Storage container
	int count=0;  //Counter
	//Storage production
	public synchronized void push(Goods good) {
		//When can production containers exist
		//No production, only waiting
		if(count==goods.length) {
			try {
				this.wait();  //Thread blocking consumer notifies production release
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//There is room for production
		goods[count]=good;
		count++;
		//There is data to inform consumption
		this.notifyAll();
	}
	//Obtain consumption
	public synchronized Goods pop() {
		//When is there data in the consumer container
		//No data can only wait
		if(count==0) {
			try {
				this.wait();  //Thread blocking producer notifies consumer to release
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//Existing data can be consumed
		count--;
		Goods good=goods[count];
		this.notifyAll();  //There is room to awaken each other's production
		return good;
	}
}
//commodity
class Goods{
	int id;

	public Goods(int id) {
		super();
		this.id = id;
	}
	
}

25. Multithreading_ Concurrent collaboration_ Signal lamp

  • Collaboration model: producer consumer implementation mode 2: signal lamp
  • With the help of flag bit
public class TestXinhaoDe {
	public static void main(String[] args) {
		TV tv=new TV();
		new Player(tv).start();
		new Listener(tv).start();
	}
}
//Producer actor
class Player extends Thread{
	TV tv;
	public Player(TV tv) {
		super();
		this.tv = tv;
	}
	public void run() {
		for(int i=0;i<20;i++) {
			if(i%2==0) {
				this.tv.play("music");
			}else {
				this.tv.play("movie");
			}
		}
	}
}
//Consumer audience
class Listener extends Thread{
	TV tv;
	public Listener(TV tv) {
		super();
		this.tv = tv;
	}
	public void run() {
		for(int i=0;i<20;i++) {
			tv.Watch();
		}
	}
}
//Same resource TV
class TV{
	String voice;
	//Signal lamp
	//T means the actor performs and the audience waits
	//F means the audience watches the actors wait
	boolean flag=true;
	
	//perform
	public synchronized void play(String voice) {
		//Actor waiting
		if(!flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//perform
		System.out.println("Performed"+voice);
		this.voice=voice;
		//awaken
		this.notifyAll();
		//Switch flag
		this.flag=!this.flag;
	}
	//watch
	public synchronized void Watch() {
		//Audience waiting
		if(flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//watch
		System.out.println("Yes"+voice);
		//awaken
		this.notifyAll();
		//Switch flag
		this.flag=!this.flag;
	}
}

26. Multithreading_ Advanced topics_ Timing scheduling

Task scheduling: with the help of Timer and TimerTask classes

public class TestTiime {
	public static void main(String[] args) {
		Timer time=new Timer();
		//Implementation arrangements
//		time.schedule(new MyTask(),1000); // Perform the task once
//		time.schedule(new MyTask(),1000,200);  // Execute multiple times
		Calendar cal=new GregorianCalendar(2021,12,30,12,30,20);
//		time. schedule(new MyTask(),new Date(5000L),200); // Start in 5 seconds
		time.schedule(new MyTask(),cal.getTime(),200);
		
	}
}

//Task class
class MyTask extends TimerTask{
	@Override
	public void run() {
		for(int i=0;i<10;i++) {
			System.out.println("Take a break");
		}
		System.out.println("-----end------");
	}
}

27. Multithreading_ Advanced topics_ QUARTZ

Official website: quartz

28. Multithreading_ Advanced topics_ happenbefore

HappenBefore: the order of executing code may be inconsistent with that of the written code, that is, if the virtual machine optimizes the code order, it is instruction rearrangement.
Data dependency:

  • (1) Read after writing a=1;b=a;
  • (2) Write after write: a=1;a=2;
  • (3) Write after reading: a=b;b=1;
    In the above three cases, as long as the execution order of the two operations is reordered, the execution result of the program will be changed. Therefore, compiler and processor will abide by data dependency when reordering. The compiler and processor do not change the execution order of the two operations of the data dependency.
/*
 * Instruction rearrangement: the execution order of the code is inconsistent with that expected
 * Objective: to improve performance
 */
public class Test {
	//Variable 1
	private static int a=0; 
	//Variable 2
	private static boolean flag=false;
	public static void main(String[] args) throws InterruptedException {
		//Thread 1 changes data
		Thread t1=new Thread(()->{
			a=1;
			flag=true;
		});
		//Thread 2 reads data
		Thread t2=new Thread(()-> {
			if(flag) {
				a*=1;
			}
			//Instruction rearrangement
			if(a==0) {
				System.out.println("happen before a"+a);
			}
		});
		t1.start();
		t2.start();
		t1.join();
		t2.join();
	}
}

The code has some problems and does not get the correct output. If anyone knows what's wrong, please leave a comment!

29. Multithreading_ Advanced topics_ volatile

volatile ensures the visibility of variables between threads.
Objective: to improve efficiency
Volatile is a good mechanism, but volatile cannot guarantee atomicity.

/*
 * volatile: It is used to ensure data synchronization, that is, visibility
 */
public class Testvolatile {
//	private static int num=0;
	private volatile static int num=0; 
	public  static void main(String[] args) throws InterruptedException {
		new Thread(()->{
			while(num==0) {  //Don't write code here
				
			}
		}).start();
		Thread.sleep(1000);
		num=1;
	}
}

30. Multithreading_ Advanced topics_ dcl singleton mode

dcl singleton mode: Based on the lazy routine, it ensures that there is an external object in the multithreaded environment

  • 1. Constructor privatization – > avoid external new constructors
  • 2. Provide private static properties – > store the address of the object
  • 3. Provide public static methods – > get properties
public class Test1 {
	//2. Provide private static properties
	private volatile static Test1 instance;  //Avoid instruction rearrangement
	//Without volatile, other threads may access an object that is not initialized
	//1. Constructor privatization
	private Test1() {
		
	}
	//3. Provide public static methods
	public static  Test1 getInstance() {
		//Retest
		if(null!=instance) {  //Avoid unnecessary synchronization. Objects already exist
			return instance;
		}
		synchronized (Test1.class) {
			if(null==instance) {
				instance=new Test1();
				//(three things new does): 1. Open up space 2. Initialize object information 3. Return the address of the object to the reference
			}
		}
		return instance;
	}
	public static void main(String[] args) {
		Thread t=new Thread(()->{
			System.out.println(Test1.getInstance());
		});
		t.start();
		System.out.println(Test1.getInstance());
	}
}

31. Multithreading_ Advanced topics_ ThreadLocal

ThreadLocal is most commonly used to bind a database link, HTTP request, user identity information, etc. for each thread. All the methods called by such a thread can easily access these resources.

  • (1) HIbernate Session tool class HIbernateUtil
  • (2) Set Bean properties through different thread objects to ensure the independence of each thread Bean object.
/*
 * ThreadLoacal:Each thread's own local storage. Local area
 * get/set/initialValue
 */
public class Test3 {
//	private static ThreadLocal<Integer> threadLocal=new ThreadLocal<>();
	//Change initial value
//	private static ThreadLocal<Integer> threadLocal=new ThreadLocal<>() {
//		protected Integer initialValue() {
//			return 200;
//		};
//	};
	/*
	 * Mode 2: lambda
	 */
	private static ThreadLocal<Integer> threadLocal=ThreadLocal.withInitial(()->200);
	
	
	public static void main(String[] args) {
		//Get value
//		System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get()); //-->main-->null
		System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get()); //-->main-->200
		//Set value
		threadLocal.set(99);
		System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get()); //-->main-->99
	}
	
}

ThreadLocal: starting point of analysis context
1. Constructor: it belongs to wherever it is called
2. run method: the method of the thread itself

InheritableThreadLocal: copy the data starting point of the inherited context environment to the child thread

32. Multithreading_ Advanced topics_ Reentrant lock_ Principle realization

1) Reentrant lock: the lock can be used continuously

public class Test4 {
	public void test() {
		//Get lock for the first time
		synchronized (this) {
			while(true) {
				//Get the same lock a second time
				synchronized (this) {
					System.out.println("ReentrantLock");
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static void main(String[] args) {
		new Test4().test();
	}
}

2) Non reentrant lock

public class Test4{
	Lock lock=new Lock();
	public void a() throws InterruptedException {
		lock.lock();
		doSomething();
		lock.unlock();
	}
	//Non reentrant
	public void doSomething() {
		try {
			lock.lock();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		lock.unlock();
	}
	public static void main(String[] args) throws InterruptedException {
		Test4 test=new Test4();
		test.a();
		test.doSomething();
	}
}
//Non reentrant lock
class Lock{
	//Occupied
	private boolean isLocked=false;
	//Use lock
	public synchronized void lock() throws InterruptedException {
		while(isLocked) {
			wait();
		}
		isLocked=true;
	}
	//Release lock
	public synchronized void unlock() {
		
	}
}

33. Multithreading_ Advanced topics_ CAS_ Atomic operation

Locks fall into two categories:
(1) Pessimistic lock: synchronized is an exclusive lock, that is, a pessimistic lock. It will cause all other threads that need a lock to hang and wait for the thread holding the lock to release the lock.
(2) Optimistic lock: complete an operation without locking each time, assuming that there is no conflict. If it fails due to the conflict, try again until it succeeds.

/*
 * CAS: Compare and exchange
 */
public class CAS {
	//stock
	private static AtomicInteger stock=new AtomicInteger(5); 
	public static void main(String[] args) {
		for(int i=0;i<5;i++) {
			new Thread(()->{
				//Analog network delay
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				Integer left=stock.decrementAndGet();
				if(left<1) {
					System.out.println("It's over....");
					return ;
				}
				System.out.println(Thread.currentThread().getName()+"Robbed a commodity");
				System.out.println("-->Remaining"+left);
			}).start();
		}
	}
}

Previous blog post: Learning java_ IO_ This is enough

Keywords: Python Java C Eclipse Algorithm

Added by smilesmita on Tue, 21 Dec 2021 05:12:22 +0200