Synchronization and locking of Java multi-thread threads

Source: Internet
Author: User

First, the synchronization problem proposed

Thread synchronization is a breach of data that prevents multiple threads from accessing a data object.

For example: Two threads Threada, threadb all manipulate the same object Foo object, and modify the data on the Foo object.

Publicclass Foo {Privateint x = + Publicint GetX () {return x;     } publicint fix (int y) {x = x = y; return x; } }

publicclass myrunnable implements runnable { private foo Foo = new Foo ();  publicstaticvoid main (string[] args) {          Myrunnable R = new myrunnable ();          thread ta =  New thread (r,  "thread-a");          thread TB = new  thread (r,  "Thread-b");          ta.start ();          tb.start ();      } publicvoid run ( ) { for  (int i = 0; i < 3; i++) { this.fix (+);  try {     & Nbsp;           thread.sleep (1);              } catch  (interruptedexception e) {    &nBsp;             e.printstacktrace ();              }              system.out.println (Thread.CurrentThread (). GetName () +  ": The x value of the current Foo object = " + foo.getx ()");         }      } publicint fix (int y) { return foo.fix (y);     }  }

Operation Result:

THREAD-A: The x value of the current Foo object = Thread-b: The x value of the current Foo object = Thread-b: The x value of the current Foo object = -20 thread-a: The x value of the current Foo object = -50 thread-a: current foo x value of object = -80 Thread-b: The x value of the current Foo object = -80 Process finished with exit code 0

The result shows that the output value is obviously unreasonable. The reason is that two threads do not control access to Foo objects and modify their data as a result.

If you want to keep the results reasonable, you only have to achieve one goal, which is to restrict the access to Foo, and only one thread at a time can access it. This will ensure that the data in the Foo object is reasonable.

There are two things to do in the specific Java code:

Identify the resource class Foo variable x for the competing access as private;

Synchronize the code that modifies the variable, using the Synchronized keyword synchronization method or code.

Second, sync and lock

1, the principle of the lock

Each object in Java has a built-in lock

When the program runs to a non-static synchronized synchronization method, the lock associated with the current instance (this instance) of the executing code class is automatically obtained. Acquiring a lock on an object is also known as acquiring a lock, locking an object, locking on an object, or synchronizing on an object.

The object lock does not work until the program runs to the synchronized synchronization method or code block.

An object has only one lock. Therefore, if a thread obtains the lock, no other thread can get the lock until the first thread releases (or returns) the lock. This also means that no other thread can enter the synchronized method or block of code on the object until the lock is freed.

A release lock is a lock thread that exits the synchronized synchronization method or code block.

For lock and Sync, here are a few points:

1), can only synchronize methods, but not synchronization variables and classes;

2), each object has only one lock; when it comes to synchronization, what should be clearly synchronized? In other words, on which object is it synchronized?

3), you do not have to synchronize all the methods in the class, the class can have both synchronous and non-synchronous methods.

4), if two threads are going to execute the synchronized method in a class, and two threads use the same instance to invoke the method, only one thread can execute the method at a time, and the other
Need to wait until the lock is released. That is, if a thread obtains a lock on the object, no other thread can enter any one of the synchronization methods in the class (the object).

5), if the thread has synchronous and non-synchronous methods, the non-synchronous method can be freely accessed by multiple threads without being restricted by the lock.

6), when the thread sleeps, any locks it holds will not be released.

7), threads can obtain multiple locks. For example, a synchronous method that invokes another object in a synchronous method of an object acquires a synchronization lock for two objects.

8), synchronization damage concurrency, should be as narrow as possible synchronization range. Synchronization can not only synchronize the entire method, but also synchronize some of the code blocks in the method.

9), when using synchronous code blocks, you should specify which object to synchronize on, that is, which object to get the lock. For example:

The public int, fix (int y) {synchronized (this) {x = XY;    } return x; }

Of course, synchronous methods can also be rewritten as non-synchronous methods, but functionally identical, for example:

public synchronized int GetX () {return x + +; }

And

public int GetX () {synchronized (this) {return x; }    }

The effect is exactly the same.

Third, static method synchronization

To synchronize a static method, you need a lock for the entire class object, which is the Class (Xxx.class).

For example:

public static synchronized int setName (String name) {

Xxx.name = name;

}

Equivalent to public static int setName (String name) {synchronized (xxx.class) {xxx.name = name; }}

Iv. What happens if a thread can't get a lock?

If a thread attempts to enter the synchronization method and its lock is already occupied, the thread is blocked on the object. Essentially, a thread enters a pool of that object, where it must wait until its lock is freed and the thread becomes operational or running again.

When considering blocking, be sure to note which object is being used for locking:

1. Threads that call non-static synchronization methods on the same object will block each other. If it is a different object, each thread has its own lock on the object, and the threads do not interfere with each other.

2. Threads that call static synchronization methods in the same class will block each other, and they are all locked on identical class objects.

3. Static synchronization methods and non-static synchronization methods will never block each other, because static methods are locked on the class object, and non-static methods are locked on the object of the class.

4, for the synchronization of the code block, to see what the object has been used to lock (synchronized the contents of the parentheses behind). Threads that synchronize on the same object block each other, and threads that are locked on different objects will never block each other.

Five. When to synchronize

When multiple threads access mutually exclusive (exchangeable) data, they should be synchronized to protect the data, ensuring that two threads do not modify it at the same time.

For data that can be changed in non-static fields, it is usually accessed using a non-static method.

For data that can be changed in a static field, it is usually accessed using static methods.

If you need to use a static field in a non-static method, or if you call a non-static method in a static field, the problem becomes very complex. Has gone beyond the scope of the SJCP exam.

Vi. Thread Safety Classes

When a class is already well synchronized to protect its data, this class is called "Thread-safe."

Even thread-safe classes should be particularly cautious, because the threads of the operation are still not necessarily secure.

An example of an image, such as a collection that is thread-safe, has two threads manipulating the same collection object, when the first thread queries the collection for non-null, deleting all the elements in the collection. The second thread also comes with a
Row is the same as the first thread, perhaps after the first thread query, the second thread also queries the collection for non-null, but when the first cleanup is performed, the second delete is obviously wrong, because the collection
It's already empty.

Take a look at the code:

Publicclass namelist { private list namelist = collections.synchronizedlist (New LinkedList ( ));  publicvoid add (String name) {         namelist.add ( name);      } public string Removefirst () { if  (nameList.size () > 0 ) { return  (String) namelist.remove (0);         }  else { returnnull;         }      } }

publicclass test { publicstaticvoid main (string[] args) { final namelist nl = new  namelist ();          nl.add ("AAA"); class  Namedropper extends thread{ publicvoid run () {                  string name = Nl.removefirst ();    &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SYSTEM.OUT.PRINTLN (name);              }          }         thread T1 = new  Namedropper ();          thread T2 = new namedropper ();          t1.start ();          t2.start ();      } }

Although the collection object

Private List NameList = collections.synchronizedlist (new LinkedList ()); Is synchronous, but the program is not thread-safe.

This event occurs because, in the previous example, one of the thread action lists does not prevent another thread from being able to block other actions on the list.

The solution to the above problem is to do a synchronization on the namelist of the Action collection object. The rewritten code is as follows:

Publicclass namelist {private List namelist = collections.synchronizedlist (new LinkedList ()); publicsynchronizedvoid     Add (String name) {namelist.add (name);         } publicsynchronized String Removefirst () {if (namelist.size () > 0) {return (String) namelist.remove (0);         } else {returnnull; }     } }

This way, when one thread accesses one of the synchronization methods, the other threads wait only.

Vii. Thread Deadlock

Deadlocks are complex and difficult to find for Java programs. When two threads are blocked, a deadlock occurs when each thread waits for another thread.

Or see a more intuitive example of deadlocks:

Publicclass deadlockrisk { privatestaticclass resource { publicint value;      } private resource resourcea = new resource ();  private Resource Resourceb = new resource ();  publicint read () { synchronized  (ResourceA) {  synchronized  (RESOURCEB) { return resourceb.value + resourcea.value;              }         }      } publicvoid write (int a, int b) { synchronized  ( RESOURCEB) { synchronized  (resourcea) {                  resourcea.value = a;                  resourceb.value = b;              }         }      } }

Suppose that the read () method is started by one thread, and the Write () method is started by another thread. The read thread will have a resourcea lock, and the write thread will have a RESOURCEB lock, and both will be deadlocked if they wait.

In fact, the probability of a deadlock in the above example is very small. Because at some point within the code, the CPU must switch from a read thread to a write thread, so a deadlock cannot basically occur.

However, no matter how small the probability of a deadlock occurs in the code, the program dies once a deadlock occurs. There are some design methods that can help avoid deadlocks, including the policy of always acquiring locks in a predefined order. Has gone beyond SCJP's Test range.

Eight, thread synchronization summary

1, the purpose of thread synchronization is to protect multiple threads to ask a resource when the destruction of resources.

2, thread synchronization method is implemented by the lock, each object has a cut only a lock, the lock with a specific object, the thread once the object lock, the other access to the object's thread can no longer access the object's other synchronization methods.

3, for the static synchronization method, the lock is for this class, the lock object is the class object. Static and non-static methods of locking do not interfere. A thread acquires the lock, which is obtained when a synchronization method on another object is accessed in a synchronous method.

4, for synchronization, to be awake at all times on which object synchronization, this is the key.

5, write thread-safe classes, you need to pay attention to multiple threads competing access to the logic and security of the resources to make the right judgment, the "atomic" operation to make an analysis, and ensure that other threads during atomic operation can not access the competing resources.

6. When multiple threads wait for an object lock, the thread that does not acquire the lock will block.

7, deadlock is between the threads waiting for lock-lock caused by, in practice, the probability of occurring is very small. Really let you write a deadlock program, not necessarily good, hehe. However, once the program has a deadlock, the program will die.

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.