Java Multithreading synchronization relies on the object lock mechanism , the synchronized keyword behind is to use the blockade to achieve mutually exclusive access to shared resources.
The following is a simple example to compare and analyze. What the instance is doing is very simple: create 10 threads, each of which prints from 0 to 99 100 digits, and we want the threads to print in sequence instead of cross order.
Let's take a look at the first code, where we've added the Synchronized keyword to the run () method, hoping to be mutually exclusive to the Run method, but the result is not as we would have hoped, because this is where synchronized locks the This object, the currently running thread object itself. 10 threads are created in the code, and each thread holds the object lock of this object, which does not implement thread synchronization.
Code
Package Com.vista;
Class Mythread implements Java.lang.Runnable
{
private int threadId;
Public mythread (int id)
{
This.threadid = ID;
}
@Override
Public synchronized void Run ()
{
for (int i = 0; i < ++i)
{
System.out.println ("Thread ID:" + This.threadid + ":" + i);
}
}
}
public class Threaddemo
{
/**
* @param args
* @throws interruptedexception
*/
public static void Main (string[] args) throws Interruptedexception
{
for (int i = 0; i < ++i)
{
New Thread (New Mythread (i)). Start ();
Thread.Sleep (1);
}
}
}
As you can see from the code snippet above, to achieve synchronization of threads, these threads must compete for a unique, shared object lock.
Based on this idea, we modify the first paragraph of code as follows, and before creating a startup thread, we create a competing object for the object, and then pass the reference of the object to the lock member variable for each thread object. As a result, each thread's lock member points to the same object object. In the Run method, the lock object is partially blocked with a synchronzied block, which allows the thread to compete for the unique shared object lock, which enables synchronization.
Code
Package Com.vista;
Class Mythread implements Java.lang.Runnable
{
private int threadId;
Private Object lock;
Public mythread (int id, Object obj)
{
This.threadid = ID;
This.lock = obj;
}
@Override
public void Run ()
{
Synchronized (lock)
{
for (int i = 0; i < ++i)
{
System.out.println ("Thread ID:" + This.threadid + ":" + i);
}
}
}
}
public class Threaddemo
{
/**
* @param args
* @throws interruptedexception
*/
public static void Main (string[] args) throws Interruptedexception
{
Object obj = new Object ();
for (int i = 0; i < ++i)
{
New Thread (New Mythread (i, obj)). Start ();
Thread.Sleep (1);
}
}
}
From the second code, it is understood that the key to synchronization is that multiple thread objects compete for the same shared resource, and the above code is implemented by creating shared resources externally and then passing them to the thread. We can also use class member variables to be shared by instances of all classes, so you can implement lock with a static member object, as shown in the following code:
Code
Package Com.vista;
Class Mythread implements Java.lang.Runnable
{
private int threadId;
private static Object lock = new Object ();
Public mythread (int id)
{
This.threadid = ID;
}
@Override
public void Run ()
{
Synchronized (lock)
{
for (int i = 0; i < ++i)
{
System.out.println ("Thread ID:" + This.threadid + ":" + i);
}
}
}
}
public class Threaddemo
{
/**
* @param args
* @throws interruptedexception
*/
public static void Main (string[] args) throws Interruptedexception
{
for (int i = 0; i < ++i)
{
New Thread (New Mythread (i)). Start ();
Thread.Sleep (1);
}
}
}
To take a look at the first piece of code, the instance method adds the Sychronized keyword to block the This object itself, while in the static method the Sychronized keyword is blocked by the class itself. Static methods are shared by all class instance objects, so thread objects are mutually exclusive access to this static method, allowing synchronization of threads, as shown in the following code:
Code
Package Com.vista;
Class Mythread implements Java.lang.Runnable
{
private int threadId;
Public mythread (int id)
{
This.threadid = ID;
}
@Override
public void Run ()
{
Taskhandler (This.threadid);
}
private static synchronized void Taskhandler (int threadId)
{
for (int i = 0; i < ++i)
{
System.out.println ("Thread ID:" + threadId + ":" + i);
}
}
}
public class Threaddemo
{
/**
* @param args
* @throws interruptedexception
*/
public static void Main (string[] args) throws Interruptedexception
{
for (int i = 0; i < ++i)
{
New Thread (New Mythread (i)). Start ();
Thread.Sleep (1);
}
}
}