Example parsing java synchronized keyword and thread safety problem _ practical skills

Source: Internet
Author: User
Tags modifier thread class

First, review the basic use of synchronized:

    • Synchronized code block, the modified code to become a synchronized statement block, the scope of the function is to call the code block object, we use the Synchronized keyword, we can narrow the scope of the Code section as far as possible, can be added to the Code section on the synchronization will not be added to the whole method of synchronization. This is called reducing the size of the lock to make the code more concurrent.
    • Synchronized method, the modified method becomes the synchronization method, whose scope is the whole method, and the object is the object that calls the method.
    • Synchronized a static method that modifies a static method that is scoped to the entire static method, and the object is all objects of the class.
    • The synchronized class, which is scoped to the part of the synchronized followed by parentheses synchronized (Classname.class), is the object of all objects of this class.
    • Synchronized () () is a locked object, synchronized (this) locks only the object itself, the Synchronized method invoked by the different objects of the same class is not locked, and synchronized ( Classname.class) implements the global lock function, all this class object calls this method to be affected by the lock, moreover () also may add a concrete object, realizes to the concrete object lock.
Synchronized (object) {
 //operation of objects in a synchronized code block 
}

Synchronized keyword and thread safety
I think it's safe to thread-sync if you use the Synchronized keyword to wrap the code. Tested the next. The discovery was completely wrong. Synchronized must be used correctly for the true thread safety ... Although I know this way of writing, I always thought that I used the wrong method because of laziness.
It seems that the foundation has not been well played. Still need to review and strengthen! It is unforgivable to make such a mistake at work, to know that the place with the Synchronized keyword is data sensitive! Sweat a hand ...
First Paste code:

package com; 
 
public class ThreadTest {public 
 static void Main (string[] args) { 
  Mythread m1 = new Mythread (1); 
  Mythread m2 = new Mythread (2); 
  M1.start (); 
  M2.start (); 
 } 
 
Final class Mythread extends Thread { 
 private int val; 
 
 public mythread (int v) { 
  val = v; 
 } 
 This practice is actually not thread-safe public 
 synchronized void print1 (int v) {for 
  (int i = 0; i < i++) { 
   System.out.prin T (v); 
  } 
 } 
 
 public void Print2 (int v) { 
  //thread safety 
  synchronized (mythread.class) {for 
   (int i = 0; i < i++) { 
    System.out.print (v); 
 
 }}} public void Run () { 
  print1 (val); 
  Print2 (val); 
 } 
 

Or to be lazy, sweat a ... Programmers are always lazy. Write less if you can. I wrote mythread into an anonymous final inner class for easy invocation. It uses the most direct inheritance thread to implement a thread class that defines the run () method that needs to be running.
First, annotate the Print2 () method to see the results of print1 (). Print1 () is a method that uses the Synchronized keyword definition, and I always thought it would be thread-safe. Everyone knows, I was wrong.
Let's run the main () method directly. The console prints the results as follows:

Copy Code code as follows:

1212111121212121212121212121212121212121222222212121212..


is a series of 1 and 2 cross print results. And my main method is to run the M1 before running the M2, showing that the thread is not synchronized!

Mythread m1 = new Mythread (1); 
Mythread m2 = new Mythread (2); 
M1.start (); 
M2.start (); 

Next we comment out the print1 () in the Run method and run Print2 ();
The console prints as follows:

Copy Code code as follows:

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111222222222222222222222 2222222222222222222222222222222222222222222222222222222222222222222222222222222

The thread is really safe, always thought to know this way of writing, but because the code is a little more than a little bit of thinking, today to realize this error. Sometimes it's good to be lazy. It is important to lay a good foundation. Corrected a long mistake.

Let's look at the specific reasons.

The Synchronized keyword can be used as a modifier of a function, or as a statement within a function, which is usually a synchronized method and a block of synchronized statements. In the finer categories, synchronized can be used for instance variables, object reference (reference), static functions, and class literals (class name literal constants).
Before we further elaborate, we need to be clear on a few points:
A Whether the Synchronized keyword is added to a method or an object, the lock it obtains is an object rather than a piece of code or function as a lock-and the synchronization method is likely to be accessed by objects of other threads.
B Each object has only one lock (lock) associated with it.
C To achieve synchronization is a very large system overhead as a cost, and may even cause deadlock, so try to avoid unnecessary synchronization control.
Next, discuss synchronized's impact on the code in different places:
Assuming that P1, P2 are different objects of the same class, this class defines synchronization blocks or synchronization methods that can be invoked by P1, P2, and so on.
1. When you treat synchronized as a function modifier, the sample code is as follows:

Public synchronized void Methodaaa () 
{ 
//... 
} 

This is also the synchronization method, then synchronized locked is what object? It locks a call to this synchronization method object. That is, when an object P1 the synchronization method in a different thread, they form a mutex that achieves the effect of synchronization. But another object generated by the class that this object belongs to P2 can invoke the method that was added to the Synchronized keyword arbitrarily.
The example code above is equivalent to the following code:

public void Methodaaa () 
{ 
synchronized (this)//(1) 
{ 
//... 
} 
}} 

(1) What does this refer to? It refers to the object that invokes this method, such as P1. The visible synchronization method is essentially a synchronized action on the object reference. -The thread that got the lock on the P1 object can call the P1 synchronization method, and for P2, P1 this lock is irrelevant to it, the program may also in this case to get rid of synchronization mechanism control, resulting in data chaos!

2. Sync block, sample code as follows:

public void method3 (Someobject i) 
{ 
synchronized (so) 
{ 
//... 
} 


Then the lock is the object of so, and whoever gets the lock can run the code it controls. When there is a clear object as a lock, you can write the program, but when there is no clear object as a lock and just want to synchronize a piece of code, you can create a special instance variable (it has to be an object) to act as a lock:

Class Foo implements Runnable 
{ 
private byte[] lock = new byte[0];//Special instance variable public 
void MethodA () 
   { 
synchronized (lock) {//...} 
} 
.... 
} 

Note: A 0-length byte array object is created more economically than any object--view compiled bytecode: A 0-length byte[] object takes only 3 opcode, while object lock = new Object () requires 7 rows of opcode.
3. The synchronized is applied to the static function, and the sample code is as follows:

 "class Foo {public synchronized static void Methodaaa ()//synchronous static function {//...} public void methodbbb () {synchronized (Foo.class)//class literal (class name literal constant)}} 

The METHODBBB () method in the code is to use class literal as a lock, and it produces the same effect as the synchronized static function, and the lock is special, the class that the object that is currently calling the method belongs to (class, Instead of being a specific object generated by this class.
Remember in the book "Effective Java" that the Foo.class and P1.getclass () used as a synchronous lock is not the same, can not use P1.getclass () to achieve the purpose of locking this class. P1 refers to objects that are generated by the Foo class.
It can be inferred that if a class has defined a synchronized static function A and also defines a synchronized instance function B, then the same object obj of this class will not constitute a synchronization when accessing A and B two methods, respectively, in multiple threads. Because their locks are not the same. The lock of a method is the object of obj, and the lock of B is the class that obj belongs to.
The summary is as follows:
figuring out which object the synchronized is locking can help us design more secure multithreaded programs.
There are also some techniques that make it more secure to synchronize access to shared resources:
1. Define private instance variable + its get method instead of defining public/protected instance variables. If you define a variable as public, the object can get it directly and change it in the outside world by bypassing the control of the synchronization method. This is also one of the standard implementations of JavaBean.
2. If the instance variable is an object, such as an array or ArrayList, the above method is still unsafe, because when an external object gets a reference to the instance object through the Get method and points it to another object, the private variable is changed, It's dangerous. At this point, you need to synchronize the Get method with synchronized, and return only the Clone () of the private object-so that the caller gets a reference to the object's copy.

Summarize some synchronized notes:

    • When two concurrent threads access a synchronized code block in the same object, only one thread can be executed at the same time and another thread is blocked, and the code block must wait until the current thread has finished executing the code block. Two threads are mutually exclusive, because the current object is locked when the synchronized code block is executed, and the next thread can execute and lock the object only if the block of code is executed to release the object lock.
    • When a thread accesses a synchronized (this) synchronization code block of object, another thread can still access a non-synchronized (this) synchronized code block in that object. (Two threads are using the same object)
    • When a thread accesses a synchronized (this) synchronized code block of object, access to all other synchronized (this) synchronized code blocks in object is blocked (IBID., two threads use the same object).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.