Java Multi-thread synchronized (i)

Source: Internet
Author: User

As mentioned in the previous section, "Non-thread-safe" is how it appears, with the following links: http://www.cnblogs.com/chentong/p/5650137.html, how to solve the "non-thread-safe" problem? Just add the Synchronized keyword in front of the two threads that require simultaneous access, and I'll just post the code for the method that needs to be modified, as follows:

     public static class Getnum {private int num = 0;                Two threads must be thread safe to access a synchronization method in the same object synchronizedpublic void Getnum (String name) {try {if ("a". Equals (name)) {num = 100 ; System.out.println ("A set over"); Thread.Sleep (2000);} else {num = 200; System.out.println ("B set Over");} SYSTEM.OUT.PRINTLN ("thread" + name + "num=" + num);} catch (Exception e) {e.printstacktrace ();}}}

  The results are as follows: no matter which thread executes first, there must be no cross-execution, because synchronized gets an object lock, and in the main method there is only one Getnum object num (I don't know how the main method is called, you can see a blog, the link above is already attached), So there is only one lock, so only one thread has finished executing the Run method before releasing the lock and the other thread will execute. Therefore, in the case of only one object lock, the method of synchronized declaration must be queued.

the above situation is an object a lock, the following is how multiple objects more than one lock is executed. The example code is as follows:

public static void Main (string[] args) {getnum num1 = new Getnum (); Getnum num2 = new Getnum ();Threada a = new Threada (NUM1); A.start (); THREADB B = New Threadb (num2); B.start ();} public static class Getnum {private int num = 0;synchronizedpublic void Getnum (String name) {try {if ("a". Equals (name)) {num = 100; System.out.println ("A set over"); Thread.Sleep (2000);} else {num = 200; System.out.println ("B set Over");} SYSTEM.OUT.PRINTLN ("thread" + name + "num=" + num);} catch (Exception e) {e.printstacktrace ();}}}
public static class Threada extends Thread {private getnum num;public Threada (getnum num) {super (); this.num = num;} @Overridepublic void Run () {super.run (); Num.getnum ("a");}} public static class Threadb extends Thread {private getnum num;public threadb (getnum num) {super (); this.num = num;} @Overridepublic void Run () {super.run (); Num.getnum ("B");}}

The results of the operation are as follows: You will find that the result of the printing is cross, because synchronized is the object lock, and here two threads are not the same Getnum object (NUM1 and num2), So synchronized obtained is two different locks, everyone does not affect each other. Only which thread can grab the CPU and which thread executes it.

The above two examples are accessed by the Synchronized keyword declaration method, then if there are other ordinary methods are invoked, how will be executed, below I wrote an example to illustrate this situation, as follows:

public static void Main (string[] args) {MyObject object = new MyObject (); Threada a = new Threada (object); A.setname ("a"); THREADB B = new Threadb (object), B.setname ("B"); A.start (); B.start ();} public static class MyObject {//synchronized declaration method synchronized public void Meathoda () {try {System.out.println ("Begin MethodA Threename=" + thread.currentthread (). GetName ()); Thread.Sleep (5000); System.out.println ("Meathoda endtime=" + system.currenttimemillis ());}                catch (Interruptedexception e) {e.printstacktrace ();}} Normal method public void Meathodb () {try {System.out.println ("Begin MethodB Threename=" + thread.currentthread (). GetName ()); System.out.println ("Meathodb begintime=" + system.currenttimemillis ()); Thread.Sleep (5000); System.out.println ("End");} catch (Interruptedexception e) {e.printstacktrace ();}}}  public static class Threada extends Thread {private MyObject object;public Threada (MyObject object) {super (); this.object = object;} @Overridepublic void Run () {super.run ();
Thread A invokes the synchronized declaration of the method Object.meathoda ();}} public static class Threadb extends Thread {private MyObject object;public threadb (MyObject object) {super (); this.object = object;} @Overridepublic void Run () {super.run ();
Thread B calls the Normal method Object.meathodb ();}}

 The output is as follows: The visible output is cross, indicating that thread B can invoke a method of non-synchronized type in the MyObject class in an asynchronous manner

As mentioned above, the synchronized method and the common method call, then the Synchronized method/block internal call other synchronized method/block when, is how the situation, I wrote a small example, as follows:

public static void Main (string[] args) {MyThread t = new MyThread (); T.start ();} public static class Service {synchronizedpublic voidService1 (){System.out.println ("Service1");Service2 ();}synchronizedpublic voidService2 (){System.out.println ("Service2");Service3 ();}synchronizedpublic voidService3 (){System.out.println ("Service3");}} public static class MyThread extends Thread {@Overridepublic void Run () {//TODO auto-generated method Stubsuper.run (); Service s = new service (); s.Service1 ();}}

   The results of the operation are as follows: from the running result you can derive a concept of "reentrant lock": You can get your own internal lock again. Indicates that if a thread acquires an object lock, the object lock is not released and can be obtained when it wants to acquire the object lock again.

synchronized "can be re-entered lock" There is another feature, what is it? I have written an example that can be viewed as follows:

public static void Main (string[] args) {MyThread t = new MyThread (); T.start ();} public static class MyThread extends Thread {@Overridepublic void run () {super.run (); Sub Sub = new sub ();Sub.openratesubmenthod ();}}}//sub and main two external class class Sub extends main {synchronizedpublic voidOpenratesubmenthod (){//using the i=10 defined by the parent classwhile (i > 0) {i--;try {System.out.println ("sub print i=" + i); Thread.Sleep (100);
Call the Openratemainmenthod () method of the parent class this.Openratemainmenthod ();} catch (Exception e) {e.printstacktrace ();}} }} class Main {public int i = 10;synchronizedpublic voidOpenratemainmenthod (){i--;try {System.out.println ("main print i=" + i); Thread.Sleep (100);} catch (Interruptedexception e) {e.printstacktrace ();}}
The result is as follows: In the Run method that executes the child thread Mythread, the sub-class sub is called to override the Operatemainmenthod () method in the parent class, and the Operatemainmenthod () in the Sub-class sub The Synchronized method of the parent class is called in the method, and as can be seen from the execution result, "reentrant lock" is supported in an environment that inherits from the parent-child class.

it says that "reentrant lock" is supported in the context of parent-child class inheritance, but synchronization is not inherited, and in order to prove this, I have written a small example, as follows:

public class Test09 {public-static void main (string[] args) {child-c = new Child (); Mythreasa a = new Mythreasa (c); A.setname ("a"); MYTHREASB B = new MYTHREASB (c); B.setname ("B"); A.start (); B.start (); public static class Mythreasa extends Thread {private child c;public Mythreasa (child c) {super (); this.c = C;} @Overridepublic void Run () {//TODO auto-generated method Stubsuper.run (); C.servicemethod ();}} public static class MYTHREASB extends Thread {private child c;public MYTHREASB (child c) {super (); this.c = C;} @Overridepublic void Run () {//TODO auto-generated method Stubsuper.run (); C.servicemethod ();}}}
Child and parent Two external classes, subclasses and parents, class children extends parent {@Overridepublic voidServicemethod (){try {System.out.println ("int child next Sleep begin Threadname=" + thread.currentthread (). GetName () + "time=" + system.cur Renttimemillis ()); Thread.Sleep (5000); SYSTEM.OUT.PRINTLN ("int child Next sleep end Threadname=" + Thread.CurrentThread (). GetName () + "time=" + System.currenttimemillis ());} catch (Interruptedexception e) {//TODO auto-generated catch Blocke.printstacktrace ();}}} Class Parent {synchronizedpublic voidServicemethod (){try {System.out.println ("int parent next sleep begin Threadname=" + thread.currentthread (). GetName () + "time=" + system.cu Rrenttimemillis ()); Thread.Sleep (5000); SYSTEM.OUT.PRINTLN ("int parent Next sleep end Threadname=" + Thread.CurrentThread (). GetName () + "time=" + System.currenttimemillis ());} catch (Interruptedexception e) {//TODO auto-generated catch Blocke.printstacktrace ();}}}

The result of the operation is as follows: from the running results, it can be seen that thread A and thread B intersect, there is no synchronization, the Servicemethod () method of the subclass does not have the characteristics of synchronized, If there is a synchronized feature, the execution result should be synchronous, that is, after a thread has finished executing, the other thread can execute. If you want to make the subclass of the method also have synchronized characteristics need to be in front of this method to receive add synchronized keyword.

After adding the Synchronized field before the Servicemethod () method of the child class, the execution results are as follows:

All of these are synchronized object monitors for use when objects, that is, the lock is an object lock, but here the keyword synchronized are used to declare the method, the drawbacks and how to improve what I will say in the next section.

  

 

Java Multi-thread synchronized (i)

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.