Java multithreading guide for beginners (10): Use the Synchronized keyword to synchronize class methods

Source: Internet
Author: User

To solve the "dirty data" problem, the simplest method is to use the synchronized keyword to synchronize the run method. The Code is as follows:

Public synchronized void run ()
{

}

From the code above, we can see that as long as the synchronized keyword is added between void and public, the run method can be synchronized. That is to say, for object instances of the same Java class, the run method can only be called by one thread at the same time. Only after the current run is executed can it be called by other threads. Even if the current thread executes the yield method in the run method, It just suspends it. Because other threads cannot execute the run method, the execution will continue by the current thread. Let's take a look at the following code:


The sychronized keyword is bound to only one object instance.

Class Test
{
Public synchronized void method ()
{

}
}

Public class Sync implements Runnable
{
Private Test test;
Public void run ()
{
Test. method ();
}
Public Sync (Test)
{
This. test = test;
}
Public static void main (String [] args) throws Exception
{
Test test1 = new Test ();
Test test2 = new Test ();
Sync sync1 = new Sync (test1 );
Sync sync2 = new Sync (test2 );
New Thread (sync1). start ();
New Thread (sync2). start ();
}
}


The method in the Test class is synchronized. However, the above Code creates two Test class instances. Therefore, the methods of test1 and test2 are executed separately. To synchronize a method, you must input an instance of the same Test class to its constructor when creating an instance of the Sync class, as shown in the following code:

Sync sync1 = new Sync (test1); you can not only use synchronized to synchronize non-static methods, but also use synchronized to synchronize static methods. You can define the method as follows:
Class Test
{
Public static synchronized void method (){}
}

The object instance of the Test class is as follows:

Test test = new Test ();
For static methods, if the synchronized keyword is added, this method is synchronous, whether it is using test. method (), or use Test. method () is used to call the method. The methods are synchronized and there is no problem with multiple instances of non-static methods.

In the Singleton mode of the 23 design modes, if the design is based on the traditional method, it is also thread unsafe. The following code is a single-piece mode with thread unsafe.


Package test;

// Thread-safe Singleton Mode
Class Singleton
{
Private static Singleton sample;

Private Singleton ()
{
}
Public static Singleton getInstance ()
{
If (sample = null)
{
Thread. yield (); // to enlarge the Thread security in Singleton Mode
Sample = new Singleton ();
}
Return sample;
}
}
Public class MyThread extends Thread
{
Public void run ()
{
Singleton singleton = Singleton. getInstance ();
System. out. println (singleton. hashCode ());
}
Public static void main (String [] args)
{
Thread threads [] = new Thread [5];
For (int I = 0; I <threads. length; I ++)
Threads [I] = new MyThread ();
For (int I = 0; I <threads. length; I ++)
Threads [I]. start ();
}
}


The above code calls the yield method to make the thread in single-piece mode insecure. If this line is removed, the above implementation will still be thread insecure, but it is much less likely to appear.

The program running result is as follows:


25358555
26399554
7051261
29855319
5383406


The above running results may be all the same in different running environments, but the output of these five lines is generally not the same. From this output, we can see that the getInstance method has five object instances, rather than the Expected One. This is because when a Thread executes Thread. yield (), the CPU resources are handed over to another Thread. Since the statement for creating a Singleton object instance is not executed during switching between threads, these threads have passed the if judgment. Therefore, five object instances will be created (four or three object instances may be created, depending on how many threads passed the if judgment before creating the Singleton object, the results may be different during each running ).

To make the preceding single-piece mode thread-safe, you only need to add the synchronized keyword to getInstance. The Code is as follows:

Public static synchronized Singleton getInstance (){}
Of course, there is a simpler way to create a Singleton object when defining the Singleton variable. The Code is as follows:


Private static final Singleton sample = new Singleton ();

Then, return the sample directly in the getInstance method. This method is simple, but I do not know how flexible it is to create a Singleton object in the getInstance method. Readers can choose different methods to implement the single-piece mode based on their specific needs.

Note the following when using the synchronized keyword:


1. the synchronized keyword cannot be inherited.

Although synchronized can be used to define a method, synchronized is not part of the method definition. Therefore, the synchronized keyword cannot be inherited. If a method in the parent class uses the synchronized keyword and overrides this method in the subclass, this method in the subclass is not synchronized by default, the synchronized keyword must be explicitly added to the subclass method. Of course, you can also call the corresponding methods in the parent class in the subclass method. Although the methods in the subclass are not synchronized, The subclass calls the synchronous method of the parent class. Therefore, the subclass method is equivalent to synchronization. The sample code for the two methods is as follows:

Add the synchronized keyword to the subclass method.


Class Parent
{
Public synchronized void method (){}
}
Class Child extends Parent
{
Public synchronized void method (){}
}


Call the synchronization method of the parent class in the subclass Method

Class Parent
{
Public synchronized void method (){}
}
Class Child extends Parent
{
Public void method () {super. method ();}
}


2. You cannot use the synchronized keyword when defining interface methods.

3. the constructor cannot use the synchronized keyword, but you can use the synchronized block to be discussed in the next section for synchronization.

4. synchronized can be freely placed.

In the previous example, the synchronized keyword is placed before the return type of the method. However, this is not the only location where synchronized can be placed. In a non-static method, synchronized can also be placed at the beginning of the method definition. In a static method, synchronized can be placed before static. The Code is as follows:

Public synchronized void method ();
Synchronized public void method ();
Public static synchronized void method ();
Public synchronized static void method ();
Synchronized public static void method ();


Note that synchronized cannot be placed behind the return type of the method. The following code is incorrect:

Public void synchronized method ();
Public static void synchronized method ();


The synchronized keyword can only be used for Synchronous methods.

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.