Copy Code code as follows:
Public synchronized void Run ()
{
}
As you can see from the above code, as long as you add the synchronized keyword between void and public, you can synchronize the Run method, that is, for an object instance of the same Java class, the Run method can be invoked by only one thread at a time, and the current run execution is finished. To be invoked by another thread. Even if the current thread executes the yield method in the Run method, it just pauses. Because other threads cannot execute the Run method, it will eventually continue to be performed by the current thread. Let's look at the following code:
The Sychronized keyword is bound only to an object instance
Copy Code code as follows:
Class Test
{
Public synchronized void Method ()
{
}
}
public class Sync implements Runnable
{
Private test test;
public void Run ()
{
Test.method ();
}
Public Sync (test 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 ();
}
}
Method methods in the test class are synchronized. However, the above code creates an instance of two test classes, so the method methods for Test1 and Test2 are executed separately. For method to be synchronized, you must pass an instance of the same test class to its constructor when you create an instance of the Sync class, as shown in the following code:
Sync sync1 = new sync (test1);
Not only can you use synchronized to synchronize Non-static methods, but you can also use synchronized to synchronize static methods. You can define method methods as follows:
Copy Code code as follows:
Class Test
{
public static synchronized void method () {}
}
The object instance that establishes the test class is as follows:
Test test = new test ();
For static methods, as long as the Synchronized keyword is added, this method is synchronized, whether using Test.method () or using Test.method () to invoke method methods, which are synchronized. There is no problem with multiple instances of non-static methods.
Single-piece (Singleton) patterns in 23 design patterns are designed in a traditional way and are not thread-safe, and the following code is a single piece of thread-unsafe mode.
Copy Code code as follows:
Package test;
Thread-Safe Singleton mode
Class Singleton
{
private static Singleton sample;
Private Singleton ()
{
}
public static Singleton getinstance ()
{
if (sample = = null)
{
Thread.yield (); To magnify thread insecurity 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 threading of a single piece mode appear, if the line is removed, the above implementation is still thread unsafe, but the likelihood of appearing is much smaller.
The results of the program's operation are as follows:
Copy Code code as follows:
25358555
26399554
7051261
29855319
5383406
The results of the above operation may have all the same in different operating environments, but generally the output of the five elements will not be exactly the same. From this output, we can see that the object instance obtained by the GetInstance method is five, not one we expect. This is because when a thread executes the Thread.yield (), the CPU resources are handed over to another thread. Because no statements are executed to create the Singleton object instance when the thread is switched between threads, they all pass the if judgment, so that the creation of five object instances (four or three object instances may be created). This depends on how many threads pass the if judgment before the singleton object is created, and each run may result in a different outcome.
To make the above single piece mode become thread safe, just add the Synchronized keyword to the 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 a singleton variable, as follows:
Private static final Singleton sample = new Singleton ();
You can then return the sample directly to the GetInstance method. Although this approach is simple, it is not known to be flexible in creating singleton objects in the GetInstance method. The reader can choose to use different methods to realize the single piece mode according to the specific requirements.
The following four points need to be noted when using the Synchronized keyword:
1. The synchronized keyword cannot be inherited.
Although you can use synchronized to define a method, synchronized is not part of the method definition, so the Synchronized keyword cannot be inherited. If a method in a parent class uses the Synchronized keyword and overrides the method in a subclass, the method in the subclass is not synchronized by default, and it must be explicitly added to this method of the subclass synchronized keyword. Of course, the corresponding method in the parent class can also be called in the subclass method, so that although the method in the subclass is not synchronized, the subclass invokes the synchronization method of the parent class, so the method of the subclass is equivalent to synchronization. The example code for both of these approaches is as follows:
Add the Synchronized keyword to the subclass method
Copy Code code as follows:
Class Parent
{
Public synchronized void Method () {}
}
Class Child extends Parent
{
Public synchronized void Method () {}
}
To invoke the synchronization method of the parent class in a subclass method
Copy Code code as follows:
Class Parent
{
Public synchronized void Method () {}
}
Class Child extends Parent
{
public void Method () {Super.method (); }
}
2. You cannot use the Synchronized keyword when defining an interface method.
3. The constructor method cannot use the Synchronized keyword, but can be synchronized using the synchronized block discussed in the next verse.
4. Synchronized can be placed freely.
Used in the previous example, the Synchronized keyword is placed before the return type of the method. But this is not synchronized can be placed in a unique location. In Non-static methods, synchronized can also be placed at the top of the method definition, in a static method where synchronized can be placed in front of the static code as follows:
Copy Code code 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, however, that synchronized cannot be placed after the method return type, as the following code is incorrect:
Copy Code code as follows:
public void synchronized method ();
public static void Synchronized method ();
The Synchronized keyword can only be used to synchronize methods and cannot be used to synchronize class variables, as the following code is also wrong.
Copy Code code as follows:
public synchronized int n = 0;
public static synchronized int n = 0;
While using the Synchronized keyword synchronization method is the safest way to synchronize, using a large number of synchronized keywords can result in unnecessary resource consumption and performance loss. While the synchronized lock is a method on the surface, the synchronized is actually locked into a class. That is, if synchronized is used in Non-static methods Method1 and METHOD2 definitions, METHOD2 cannot be performed until METHOD1 is not executed. A static method is similar to a non-static method. However, static and Non-static methods do not affect each other. Look at the following code:
Copy Code code as follows:
Package test;
public class MyThread1 extends Thread
{
Public String methodname;
public static void Method (String s)
{
System.out.println (s);
while (true)
}
Public synchronized void Method1 ()
{
Method ("Non-static method1 methods");
}
Public synchronized void Method2 ()
{
Method ("Non-static method2 methods");
}
public static synchronized void Method3 ()
{
Methods ("Static Method3 method");
}
public static synchronized void Method4 ()
{
Methods ("Static Method4 method");
}
public void Run ()
{
Try
{
GetClass (). GetMethod (methodname). Invoke (this);
}
catch (Exception e)
{
}
}
public static void Main (string[] args) throws Exception
{
MyThread1 myThread1 = new MyThread1 ();
for (int i = 1; I <= 4; i++)
{
Mythread1.methodname = "Method" + string.valueof (i);
New Thread (MYTHREAD1). Start ();
Sleep (100);
}
}
}
The results of the operation are as follows:
Copy Code code as follows:
Method1 method of non-static
The static Method3 method
You can see from the results above that METHOD2 and METHOD4 cannot run until method1 and method3 are not finished. Therefore, we can conclude that if you use the Synchronized keyword in a class to define a Non-static method, that will affect all non-static methods that are defined using the Synchronized keyword. If a static method is defined, it affects all static methods defined in the class using the Synchronized keyword. This is a bit like a table lock in a datasheet, and when you modify a record, the system locks the entire table, so a large amount of this synchronization can degrade the performance of the program significantly.