5. Multithreading Security issues: Multi-threaded synchronization
Thread safety issues often occur when you use multiple threads to access one data at a time. such as the following procedures:
1 package Thread; 2 3/* 4 * Security issues that occur when multiple threads access one data at a time. 5 * Simulate a train ticket system: A total of 100 tickets, multiple windows simultaneously sell tickets 6 */7 class Ticks implements Runnable 8 {9 private int Ticks = 100; 10 Public Void Run () one { ticks > 0) {+// Join the Sleep method to more clearly see the security issues that appear in the program. Try{thread.sleep (10);} catch (Exception e) {} System.out.println (Thread.CurrentThread (). GetName () + "... Sold the "+ticks+" ticket); ticks-- }20 }21}22 public class Text1 {All public static void main (String a Rgs[]) {// create Runnable object that implements class Ticks. Ticks t = new Ticks (); open 4 threads to process the same T object. new Thread (t, "one Window"). Start (); new Thread (T, "Window No. second"). Start (); new Thread (T, "window Third"). Start (); New Thread (T, "Window No. fourth"). Start (); }33}
The result of the run will appear "X Window ... Sold the first 1 tickets "," X Window ... The security issue of "2 tickets" was sold.
Cause: When multiple statements share data on the same thread, one of the threads executes only a portion of the multiple statements, not finished, and another thread participates in the execution. The error that caused the shared data.
Ways to solve this type of problem:
1. Synchronize code blocks.
2, synchronization function.
5.1 Synchronizing code blocks
The format of the synchronization code block is as follows:
Synchronized (obj) { //The code here is the synchronous code block }
The synchronized inside the parentheses is the synchronization monitor. Code meaning: Before a thread starts executing a synchronization code block, it must first obtain a lock on the synchronization monitor. That is, only the thread that obtains the lock on the synchronization monitor can execute in the synchronization, and the thread that does not lock is not executed in the synchronous code block, even if it gets execution.
Note: Although the Java program allows any object to be used as the synchronization monitor. However, it is recommended to use shared resources that may be concurrently accessed to act as synchronization monitors.
By modifying the code as follows:
1 package Thread; 2 3/* 4 * Security issues that occur when multiple threads access one data at a time. 5 * Simulate a train ticket system: A total of 100 tickets, multiple windows simultaneously sell tickets 6 */7 class Ticks implements Runnable 8 {9 private int Ticks =; IC void Run () {ticks > 0) {synchronized (Ticks.class) 15 {Ticks > 0) 17 {18//Add Sleep method for more Clearly see the security issues that appear in the program. Try{thread.sleep (10);} catch (Exception e) {} System.out.println (Thread.CurrentThread (). GetName () 21 +"... Sold the "+ticks+" ticket); ticks--; 23}24}25} 26}27 }28 public class Text1 {$ public static void main (String args[]) 30 {31///Create an Object Runnable implement class Ticks. Ticks t = new Ticks (); 33//Turn on 4 threads to handle the same T object. New Thread (T, "one Window"). Start (); New Thread (T, Window No. second).Start (); The new Thread (T, "window Third"). Start (); PNS New Thread (T, "Window No. fourth"). Start (); 38}39}
The program after joining the Sync Monitor will not have any errors on the data.
Although the advantage of synchronization monitor is that it solves the security problem of multithreading. But also because multiple threads need to determine the lock, more consumption of resources.
Note: The prerequisites for synchronization:
1, must have two or more than two threads.
2. The same lock must be used by multiple threads.
If you join the Synchronized Sync Monitor and you have a security issue, you can follow these steps to find the error:
1, clear that the code is multithreaded code.
2. Clear sharing of data.
3, clear multi-threaded running code that the code is the operation of shared data.
5.2 Synchronization functions
Use synchronized as a modifier modifier function. The function is called a synchronization function.
Note: The synchronization function does not need to display the specified synchronization monitor, which is the synchronization monitor for the synchronization function, which is the object itself.
Note: The Synchronized keyword can be decorated with methods that can decorate blocks of code, but cannot decorate constructors, properties, and so on.
The above through the simulation of train ticketing system applet, by adding synchronized synchronization monitor, to solve the multi-threading security issues. The following simulation bank to withdraw money problem, through the synchronization function to solve multi-threaded security problems.
* The basic process of bank withdraw is as follows:
* 1, the user enters the account, the password, the system determines the user's account, the password whether matches.
* 2, the user input the amount of money to withdraw.
* 3, the system determines whether the account balance is greater than the amount to withdraw money.
* 4. If the balance is greater than the withdrawal amount, the withdrawal is successful;
Only the following three steps are simulated here:
1 package Thread; 2 3 class Account {4//Balance 5 private double balance; 6 Public account (double balance) 7 {8 this.balance = balance; 9}10//Get and set method one public double getbalance () {balance;13 return}14 public void Setbala NCE (double balance) {this.balance = balance;16}17//Sync function 18//provide a thread-safe draw method to complete the money-fetching operation. Public synchronized void Draw (double drawamount) (Balance > Drawamount) 22 {23 System.out.println (Thread.CurrentThread (). GetName () + "Take the money!" Spit Amount "+ drawamount);" Try {thread.sleep (10); } catch (Exception e) {} balance-= Drawamount; System.out.println ("Card balance:" +balance); 29 }30 else {System.out.println (Thread.CurrentThread (). GetName () + "failed to withdraw money!" Card balance: "+ balance); }35}36}37 class DrawThread implements Runnable38 {39//Demo Account: 41///hope the amount of money taken is a private double drawam Ount; The private Boolean flag = true; Drawthread (account account, double drawamount). {this.account = account; 49 This.drawamount = Drawamount; 50}51//current withdraw from public void run () (Try55 {5) 8//Call the cash function on the account. Draw (Drawamount); }61}62 catch (Exception e) + {+ flag = false; 65}66} 67 }68 public class AccountText69 {$ public static void main (String args[]). {Account Account = new ACC Ount (10000), drawthread draw = new Drawthread (account), and the t = new thread (Draw, "A ... ") ; T1 thread = new Thread (Draw, "B."); T.start (); T1.start (); 78}73 ·
The monitor for the synchronization method is this, so for the same account, only one thread at any time can obtain the lock on the account object.
Tip: In order to reduce the negative impact of thread safety, the thread safety of a mutable class is to reduce the operational efficiency of the running program, and the program can use the following strategies:
> Only synchronizes the methods that will change the competing resources.
> Use synchronization in an environment where two or more two threads operate in the same lock.
The lock on the Sync Monitor is released when the following happens:
> The synchronization method of the current thread and the end of the synchronization code block execution.
> The current thread's synchronization method, the synchronization code block encountered a break, a return terminates the code block, and the method continues execution.
> The synchronization method for the current thread, an unhandled error or exception occurred in the synchronization code block, and the synchronization lock is released when the code block, the method ends abnormally.
> When a thread executes a synchronous method, synchronizes a code block, the program executes the Wait () method of the synchronization monitor object.
5.5 Dead Lock
A deadlock occurs when two threads wait for each other to release the lock. Because the JVM is not monitored, and no action is taken to handle deadlocks, the multithreading should take steps to avoid deadlocks.
6. Thread Communication
Simulated production consumers: the system has two threads, representing both the producer and the consumer.
The basic process of the program:
1, the producer produces a commodity.
2, consumer products generated by consumption.
Through the appeal process to understand: producers and consumers can not continuously generate or consume goods, while consumers can only consume to produce goods.
1 package Thread; 2 3 class Phone 4 {5//define the product's number 6 private int no; 7//define the name of the product 8 private String name; 9 Private Boolean flag = true; 10//Initialize the name and number of the product, and the number is the self-increment of the public Phone (String name, int No) {this.name = name; His. no = no; 15}16//define consumption methods and production methods in the commodity. Decorate with synchronized modifier synchronized void Production () 18 {19 20//causes the current thread to wait, knowing that other threads are calling Notif Y () or Notifyall () method to wake up//if (!flag) all while (!flag) in the try {this.wait ();} catch (Exception e) {} System.out.println (Thread.CurrentThread (). GetName () +25 ": Production" +name+ "; Number:" + + + No); 26//Wake up a single thread waiting on this sync monitor. +//This.notify (); 28//Wake up all threads waiting on this sync monitor. This.notifyall (); Flag = false;}32 public synchronized void Consumption () () +/if (flag) + Whil E (flag)-try {this.wait ();} catch (Exception e) {} 37 System.out.println (Thread.CurrentThread (). GetName () +38 "; Consumer goods:" +name+ "product is numbered" + No ";//This.notify () ; This.notifyall (); * flag = TRUE; }43}44 class Producerthread implements Runnable46 {$ phone phone; $ private Boolean flag = true; 49 Synchronization monitor Object Producerthread (phone phone) {This.phone = phone, +--Public V OID run () () () (). Production (); }61 catch (Exception e) {flag = false;} }63}64 class Consumptionthread implements RUNNABLE65 {$ 68 phone phone; Synchronization monitor Object Consumptionthread public (phone phone), {this.phone = phone; c void Run () () () (). Consumption (); }80 catch (Exception e) {FLAG = FALSE;} Bayi}82}83 public class Producerconsumertext {p-P static void Main (String args[]) Hone = new Phone ("IPhone 5", 0); Producerthread new Thread (phone), "creator". Start (); The new Thread (new Producerthread (phone), "creator 111"). Start (); Consumptionthread new Thread (phone), "consumer". Start (); The new Thread (new Consumptionthread (phone), "Consumer 111"). Start (); 91}92}
In the above procedure: the flag flag in lines 22nd and 34th is judged by whether the producer is generating or consuming by the consumer. In fact, in real life, it is impossible to have only one generator and consumer, but multiple generators and consumers. It is necessary to use the while loop to judge the flag in lines 22nd and 34th instead of using if. If you are prone to thread safety problems with if, and if you are using the while loop for flag judgment, you must use the Notifyall () method to wake all waiting threads in the synchronization monitor instead of the Notify () method. Using Notify () causes all threads to enter the wait state.
The above applet is implemented using the Wait (), notify (), and Notifyall three methods provided by the object class.
> Wait (): Causes the current thread to wait, knowing that other threads call the synchronization Monitor's notify () or Notifyall () method to wake the thread.
> Notify (): Wakes up a single thread waiting on this sync monitor. If all threads are waiting on this synchronization monitor, one of the wakes is selected.
> Notifyall (): Wakes up all the individual threads waiting on this sync monitor.
Note: These three methods must be called with a synchronization monitor object:
> Sync function: Because the default instance (this) of the class is the synchronization monitor, it can be called directly in the synchronous method.
> Synchronizing code blocks: You must use the objects in the synchronized brackets to invoke them.
7. Sync Lock Lock
After JDK 1.5, Java provides another thread synchronization mechanism: The display defines a synchronization lock for synchronization, and the synchronization lock should use the lock object to act as a.
1 class X 2 {3// Define lock object 4 private final reentrantlock lock = new Reentrantlock (); 5// ... 6// define methods that require thread safety 7 public void M () 8 {9// locking Lock.lock (); try12 {// Code to ensure thread safety }15 finally16 { lock.unlock (); }19 }20}
When using the lock object to ensure synchronization, Java provides the Condition class to maintain coordination, that is, Condition replaces the functionality of the synchronization monitor.
The Condition instance is essentially bound to a lock object. Such as:
1// define lock object 2 private final reentrantlock lock = new Reentrantlock (); 3// Specify the condition variable corresponding to the lock object 4
> await (): Similar to the Wait () method.
> Signal (): Similar to the Notify () method.
> Signalall (): Similar to the Notifyall () method.
Black Horse Programmer-java Basics-Multithreading 2