java thread state and thread scheduling
java thread synchronization
Multithreading sharing data may cause data insecurity. Threads can be locked to solve similar problems.
The first method is the synchronization method
Use the synchronized modifier to control access to class member variables
Access modifier synchronized Return type method name(parameter list){.....}
Or
synchronized Access modifier return type method name(parameter list){......}
synchronized puts a lock on the process.
package Threads; //Simulate user network ticket purchase -- > use synchronization method to solve the problem of data insecurity caused by threads public class TicketThread1 implements Runnable { private int ticket = 10;//Record the total number of tickets private int num = 0;//Record the number of tickets the user grabbed private boolean flag = false;//The delegates are sold out //Call the method of user ticket grabbing @Override public void run() { while(!flag){ sale(); } } public synchronized void sale(){ if (ticket <= 0) { flag = true; return; } //If there are spare tickets, grab them //Modify the number of tickets: the total number of tickets will be reduced by one after grabbing the tickets ticket--; //After the user grabs the tickets, the number of votes will be increased by one num++; //Analog network delay try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //Display ticket issuing feedback to users System.out.println(Thread.currentThread().getName() + "Got the third" + num + "Ticket,surplus" + ticket + "Ticket"); } }
package Test; import Threads.TicketThread1; public class TicketThread1Test { public static void main(String[] args) { Runnable runnable = new TicketThread1(); Thread t1 = new Thread(runnable); Thread t2 = new Thread(runnable); Thread t3 = new Thread(runnable); System.out.println("The parties began to scramble for votes"); t1.start(); t2.start(); t3.start(); } }
You can also synchronize code blocks:
Code block decorated with synchronized keyword
synchronized(syncObject){ //Code blocks that need to be synchronized }
syncObject is an object that needs to be synchronized, usually this
package Threads; public class TicketThread2 implements Runnable { private int ticket = 10;//Record the total number of tickets private int num = 0;//Record the number of tickets the user grabbed //User ticket grabbing @Override public void run() { while (true) { synchronized (this){ if (ticket <= 0) { break; } //If there are spare tickets, grab them //Modify the number of tickets: the total number of tickets will be reduced by one after grabbing the tickets ticket--; //After the user grabs the tickets, the number of votes will be increased by one num++; //Analog network delay try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //Display ticket issuing feedback to users System.out.println(Thread.currentThread().getName() + "Got the third" + num + "Ticket,surplus" + ticket + "Ticket"); } } } }
package Test; import Threads.TicketThread2; public class TicketThread2Test { public static void main(String[] args) { Runnable runnable = new TicketThread2(); Thread t1 = new Thread(runnable); Thread t2 = new Thread(runnable); Thread t3 = new Thread(runnable); System.out.println("The parties began to scramble for votes"); t1.start(); t2.start(); t3.start(); } }
When multiple concurrent threads access synchronous code blocks of the same resource:
Only one thread can enter the synchronized(this) synchronized code block at a time
When a thread accesses synchronized(this) synchronized code blocks, other synchronized(this) synchronized code blocks are also locked
When a thread accesses a synchronized(this) synchronized code block, other threads can access the non synchronized(this) synchronized code of the resource.
- Restrict scalpers from grabbing a ticket
package Threads; //Simulate user network ticket purchase -- > use synchronization method to solve the problem of data insecurity caused by threads public class TicketThread3 implements Runnable { private int ticket = 10;//Record the total number of tickets private int num = 0;//Record the number of tickets the user grabbed private boolean flag = false;//(1) Represents that the ticket is sold out (2) whether the thread ends flag:true thread ends //Call the method of user ticket grabbing @Override public void run() { while(!flag){ sale(); } } public synchronized void sale(){ if (ticket <= 0) { flag = true; return; } //If there are spare tickets, grab them //Modify the number of tickets: the total number of tickets will be reduced by one after grabbing the tickets ticket--; //After the user grabs the tickets, the number of votes will be increased by one num++; //Analog network delay try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //Display ticket issuing feedback to users System.out.println(Thread.currentThread().getName() + "Got the third" + num + "Ticket,surplus" + ticket + "Ticket"); //Judge whether the current thread is a scalper. If so, the thread ends and ensure to buy a ticket if(Thread.currentThread().getName().equals("Scalpers")){ flag = true; }else{ flag = false; } } }
package Test; import Threads.TicketThread3; public class TicketThread3Test { public static void main(String[] args) { Runnable runnable = new TicketThread3(); Thread t1 = new Thread(runnable,"Peach ticket"); Thread t2 = new Thread(runnable,"Kwai Chang"); Thread t3 = new Thread(runnable,"Scalpers"); System.out.println("The parties began to scramble for votes"); t1.start(); t2.start(); t3.start(); } }
- More than one person will take part in the 1000 meter relay race, each person will run 100 meters, and the next player will display information every 10 meters
package Threads; //Simulate the process of a relay run public class RunThread implements Runnable { //Multiple runners run 1000 meters together private int meters = 1000; //Realize the process that a player gets the baton and runs 100 meters @Override public void run() { while (true) { //The synchronization code block ensures that there is only one runner synchronized (this) { if (meters < 100) { break; } //One man got the baton and ran 100 meters System.out.println(Thread.currentThread().getName() + "Got the baton"); for (int i = 10; i <= 100; i += 10) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "Run away" + i + "rice"); } //The remaining road is reduced by 100m meters -= 100; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
package Test; import Threads.RunThread; public class RunThreadTest { public static void main(String[] args) { Runnable runnable = new RunThread(); Thread person1 = new Thread(runnable, "Contestant Zhang"); Thread person2 = new Thread(runnable, "Contestant Li"); Thread person3 = new Thread(runnable, "Player King"); Thread person4 = new Thread(runnable, "Player week"); Thread person5 = new Thread(runnable, "Player money"); person1.start(); person2.start(); person3.start(); person4.start(); person5.start(); } }
Thread safety
The add() method of ArrayList class is an asynchronous method. When multiple threads add data to the same ArrayList object, data inconsistency may occur. Therefore, ArrayList is a non thread safe type
/** * This helper method split out from add(E) to keep method * bytecode size under 35 (the -XX:MaxInlineSize default value), * which helps when add(E) is called in a C1-compiled loop. */ private void add(E e, Object[] elementData, int s) { if (s == elementData.length) elementData = grow(); elementData[s] = e; size = s + 1; }
Hashtable implements the Map interface. Hashtable inherits the Dictionary class. It is thread safe but inefficient. Keys and values cannot be null
HashMap implements the Map interface and inherits the AbstractMap class. It is non thread safe but efficient. Keys and values are allowed to be null
StringBuffer thread safe StringBuilder is not thread safe.
Thread safety requires methods to be synchronized, which is inefficient and suitable for multi-threaded concurrent sharing of resources.
Non thread safety is that the methods are not synchronized and the efficiency is relatively high. It is suitable for single thread.
In order to achieve the balance between security and efficiency, you can choose according to the actual scene.