synchronized Synchronization code block

With keywords synchronized Declaration methods have drawbacks in some cases , such as A The thread calls the synchronization method to perform a long task , that B The thread has to wait a long time . In this case, try to use synchronized Synchronous statement block to solve the problem . Take a look at an example :

public class ThreadDomain18
{
public void doLongTimeTask() throws Exception
{
for (int i = 0; i < 100; i++)
{
System.out.println("nosynchronized threadName = " +
Thread.currentThread().getName() + ", i = " + (i + 1));
}
System.out.println();
synchronized (this)
{
for (int i = 0; i < 100; i++)
{
System.out.println("synchronized threadName = " +
Thread.currentThread().getName() + ", i = " + (i + 1));
}
}
}
}
public class MyThread18 extends Thread
{
private ThreadDomain18 td; public MyThread18(ThreadDomain18 td)
{
this.td = td;
} public void run()
{
try
{
td.doLongTimeTask();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
ThreadDomain18 td = new ThreadDomain18();
MyThread18 mt0 = new MyThread18(td);
MyThread18 mt1 = new MyThread18(td);
mt0.start();
mt1.start();
}

Running results , In two parts :

synchronized threadName = Thread-1, i = 1
synchronized threadName = Thread-1, i = 2
nosynchronized threadName = Thread-0, i = 95
synchronized threadName = Thread-1, i = 3
nosynchronized threadName = Thread-0, i = 96
synchronized threadName = Thread-1, i = 4
nosynchronized threadName = Thread-0, i = 97
synchronized threadName = Thread-1, i = 5
nosynchronized threadName = Thread-0, i = 98
synchronized threadName = Thread-1, i = 6
nosynchronized threadName = Thread-0, i = 99
synchronized threadName = Thread-1, i = 7
nosynchronized threadName = Thread-0, i = 100
...
synchronized threadName = Thread-1, i = 98
synchronized threadName = Thread-1, i = 99
synchronized threadName = Thread-1, i = 100
synchronized threadName = Thread-0, i = 1
synchronized threadName = Thread-0, i = 2
synchronized threadName = Thread-0, i = 3
...

Two conclusions can be drawn from this experiment :

1、 When A Thread access object synchronized Block of code ,B Threads can still access the rest of the object methods synchronized The part of the block , The results of the first part prove this

2、 When A The thread enters the object's synchronized Block of code ,B If the thread wants to access this section synchronized block , Then access will be blocked , The results of the second part prove this

therefore , From the perspective of execution efficiency , Sometimes we don't have to add the whole method synchronized, It's about taking synchronized Block mode , For the part of the code that will cause thread safety problems synchronized That's all right. .

Two synchronized Blocks are mutually exclusive

If the thread 1 Accessed an object A Methodical synchronized block , So thread B For the same object B Methodical synchronized Access to the block will be blocked , Write an example to prove :

public class ThreadDomain19
{
public void serviceMethodA()
{
synchronized (this)
{
try
{
System.out.println("A begin time = " + System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("A end time = " + System.currentTimeMillis());
}
catch (InterruptedException e)
{
e.printStackTrace();
} }
} public void serviceMethodB()
{
synchronized (this)
{
System.out.println("B begin time = " + System.currentTimeMillis());
System.out.println("B end time = " + System.currentTimeMillis());
}
}
}

Write two threads to call these two methods respectively :

public class MyThread19_0 extends Thread
{
private ThreadDomain19 td; public MyThread19_0(ThreadDomain19 td)
{
this.td = td;
} public void run()
{
td.serviceMethodA();
}
}
public class MyThread19_1 extends Thread
{
private ThreadDomain19 td; public MyThread19_1(ThreadDomain19 td)
{
this.td = td;
} public void run()
{
td.serviceMethodB();
}
}

Write a main function :

public static void main(String[] args)
{
ThreadDomain19 td = new ThreadDomain19();
MyThread19_0 mt0 = new MyThread19_0(td);
MyThread19_1 mt1 = new MyThread19_1(td);
mt0.start();
mt1.start();
}

So let's see what happens :

A begin time = 1443843271982
A end time = 1443843273983
B begin time = 1443843273983
B end time = 1443843273983

See for serviceMethodB() Method synchronized Access to the block has to wait until for serviceMethodA() Method synchronized After accessing the block . In fact, this example , We can also draw a conclusion :synchronized Block gets an object lock , let me put it another way ,synchronized Blocks lock the entire object .

synchronized Block and synchronized Method

Now that there is a conclusion synchronized Block gets the object lock , So if the thread 1 Accessed an object method A Of synchronized block , Threads 2 Synchronization methods for the same object B Your access should be blocked , Because the thread 2 Synchronous methods to access the same object B You will try to get the object lock of this object , But the lock is in the thread 1 here . Write an example to prove this conclusion :

public class ThreadDomain20
{
public synchronized void otherMethod()
{
System.out.println("----------run--otherMethod");
} public void doLongTask()
{
synchronized (this)
{
for (int i = 0; i < 1000; i++)
{
System.out.println("synchronized threadName = " +
Thread.currentThread().getName() + ", i = " + (i + 1));
try
{
Thread.sleep(5);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}

Write two threads to call these two methods respectively :

public class MyThread20_0 extends Thread
{
private ThreadDomain20 td; public MyThread20_0(ThreadDomain20 td)
{
this.td = td;
} public void run()
{
td.doLongTask();
}
}
public class MyThread20_1 extends Thread
{
private ThreadDomain20 td; public MyThread20_1(ThreadDomain20 td)
{
this.td = td;
} public void run()
{
td.otherMethod();
}
}

Write a main Function call , here "mt0.start()" after sleep(100) Here's to make sure mt0 Thread starts first :

public static void main(String[] args) throws Exception
{
ThreadDomain20 td = new ThreadDomain20();
MyThread20_0 mt0 = new MyThread20_0(td);
MyThread20_1 mt1 = new MyThread20_1(td);
mt0.start();
Thread.sleep(100);
mt1.start();
}

So let's see what happens :

...
synchronized threadName = Thread-0, i = 995
synchronized threadName = Thread-0, i = 996
synchronized threadName = Thread-0, i = 997
synchronized threadName = Thread-0, i = 998
synchronized threadName = Thread-0, i = 999
synchronized threadName = Thread-0, i = 1000
----------run--otherMethod

It proves our conclusion . To further refine this conclusion , hold "otherMethod()" Methodical synchronized Take a look at the running results :

...
synchronized threadName = Thread-0, i = 16
synchronized threadName = Thread-0, i = 17
synchronized threadName = Thread-0, i = 18
synchronized threadName = Thread-0, i = 19
synchronized threadName = Thread-0, i = 20
----------run--otherMethod
synchronized threadName = Thread-0, i = 21
synchronized threadName = Thread-0, i = 22
synchronized threadName = Thread-0, i = 23
...

"otherMethod()" Methods and "doLongTask()" Methods synchronized Block executed asynchronously

Use any object as an object monitor

To summarize the previous content :

1、synchronized Synchronization method

(1) For others synchronized Synchronization method or synchronized(this) The synchronization block is blocked

(2) Only one thread can execute at a time synchronized Code in the synchronization method

2、synchronized Synchronization code block

(1) For others synchronized Synchronization method or synchronized(this) The synchronization block is blocked

(2) Only one thread can execute at a time synchronized(this) Synchronize the code in the code block

All the front uses synchronized(this) To synchronize code blocks , Actually Java Also supports the " Any object " As an object monitor to achieve synchronization function . This " Any object " Most of them are Instance variables And Method parameters , Use format as synchronized( Not this object ). Take a look at an example of using any object as an object monitor :

public class ThreadDomain21
{
private String userNameParam;
private String passwordParam;
private String anyString = new String(); public void setUserNamePassword(String userName, String password)
{
try
{
synchronized (anyString)
{
System.out.println(" The thread name is :" + Thread.currentThread().getName() +
" stay " + System.currentTimeMillis() + " Go to sync code block ");
userNameParam = userName;
Thread.sleep(3000);
passwordParam = password;
System.out.println(" The thread name is :" + Thread.currentThread().getName() +
" stay " + System.currentTimeMillis() + " Leave sync block ");
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

Write two threads and call them respectively :

public class MyThread21_0 extends Thread
{
private ThreadDomain21 td; public MyThread21_0(ThreadDomain21 td)
{
this.td = td;
} public void run()
{
td.setUserNamePassword("A", "AA");
}
}
public class MyThread21_1 extends Thread
{
private ThreadDomain21 td; public MyThread21_1(ThreadDomain21 td)
{
this.td = td;
} public void run()
{
td.setUserNamePassword("B", "B");
}
}

Write a main Function call :

public static void main(String[] args)
{
ThreadDomain21 td = new ThreadDomain21();
MyThread21_0 mt0 = new MyThread21_0(td);
MyThread21_1 mt1 = new MyThread21_1(td);
mt0.start();
mt1.start();
}

So let's see what happens :

 The thread name is :Thread-0 stay 1443855101706 Go to sync code block 
The thread name is :Thread-0 stay 1443855104708 Leave sync block
The thread name is :Thread-1 stay 1443855104708 Go to sync code block
The thread name is :Thread-1 stay 1443855107708 Leave sync block

This example proves that : Multiple threads hold " Object monitor " For the same object , Only one thread can execute at a time synchronized( Not this object x) Code in a code block .

Lock non this Objects have certain advantages : If there are many in a class synchronized Method , At this time, although synchronization can be achieved , But it's blocked , And that affects efficiency . But if the synchronization code block lock is true or false this object , be synchronized( Not this object x) The program in the code block is asynchronous to the synchronous method , Not with other locks this Synchronous method contention this lock , It greatly improves the operation efficiency .

Pay attention to the "private String anyString = new String();" this sentence , Now it's a global object , So it's monitoring the same object . If you move to try Inside , Then the object's monitor is not the same , It's called asynchronously , Try it on your own .

One last point ,synchronized( Not this object x), If this object is an instance variable , A reference to an object , As long as the reference to the object remains unchanged , Even if you change the properties of the object , The running results are still synchronized .

elaboration synchronized( Not this object x) The three conclusions of this paper are as follows

synchronized( Not this object x) The format is written in such a way that x The object itself acts as an object monitor , There are three conclusions :

1、 When multiple threads execute at the same time synchronized(x){} Synchronization of code blocks

2、 When other threads execute x Object synchronized The synchronization method is synchronous

3、 When other threads execute x Object method synchronized(this) Code blocks are also synchronized

The first point is obvious , The second point is similar to the third point , There's nothing more than synchronization , One is synchronization code block , Take an example to verify the second point :

public class MyObject
{
public synchronized void speedPrintString()
{
System.out.println("speedPrintString__getLock time = " +
System.currentTimeMillis() + ", run ThreadName = " +
Thread.currentThread().getName());
System.out.println("----------");
System.out.println("speedPrintString__releaseLock time = " +
System.currentTimeMillis() + ", run ThreadName = " +
Thread.currentThread().getName());
}
}

ThreadDomain24 Hold in MyObject References to :

public class ThreadDomain24
{
public void testMethod1(MyObject mo)
{
try
{
synchronized (mo)
{
System.out.println("testMethod1__getLock time = " +
System.currentTimeMillis() + ", run ThreadName = " +
Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("testMethod1__releaseLock time = " +
System.currentTimeMillis() + ", run ThreadName = " +
Thread.currentThread().getName());
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

Write two threads to call respectively "speedPrintString()" Methods and "testMethod1(MyObject mo)" Method :

public class MyThread24_0 extends Thread
{
private ThreadDomain24 td;
private MyObject mo; public MyThread24_0(ThreadDomain24 td, MyObject mo)
{
this.td = td;
this.mo = mo;
} public void run()
{
td.testMethod1(mo);
}
}
public class MyThread24_1 extends Thread
{
private MyObject mo; public MyThread24_1(MyObject mo)
{
this.mo = mo;
} public void run()
{
mo.speedPrintString();
}
}

Write a main Function to start the two threads :

public static void main(String[] args)
{
ThreadDomain24 td = new ThreadDomain24();
MyObject mo = new MyObject();
MyThread24_0 mt0 = new MyThread24_0(td, mo);
MyThread24_1 mt1 = new MyThread24_1(mo);
mt0.start();
mt1.start();
}

So let's see what happens :

testMethod1__getLock time = 1443855939811, run ThreadName = Thread-0
testMethod1__releaseLock time = 1443855944812, run ThreadName = Thread-0
speedPrintString__getLock time = 1443855944812, run ThreadName = Thread-1
----------
speedPrintString__releaseLock time = 1443855944812, run ThreadName = Thread-1

notice "speedPrintString()" Method must wait "testMethod1(MyObject mo)" Method can only be executed after execution , There is no way to execute asynchronously , It proves the conclusion of the second point . The verification method of the third point is similar , No code proof .

Java Multithreading 5:synchronized More articles on lock method blocks

  1. java Multithreading 9 : synchronized Locking mechanism And Code block lock

    synchronized Synchronization code block With keywords synchronized Declaration methods have drawbacks in some cases , such as A The thread calls the synchronization method to perform a long task , that B The thread has to wait a long time . In this case, try to use ...

  2. java Multithreading 8 : synchronized Locking mechanism And Method lock

    Dirty reading A common concept . In multithreading , It is hard to avoid concurrent access to instance variables or global static variables of the same object in multiple threads , If we don't do the right synchronization , So the consequence is " Dirty reading ", That is, the number obtained ...

  3. Java Multithreaded learning ——synchronized Locking mechanism

    Java When using synchronous lock mechanism in multithreading , Be sure to pay attention to the lock on the object , The following example is the object without lock ( When each thread uses a locked object , It depends on whether the locked part of the object is being used ) Example : Two people operate the same bank account , My husband is ATM ...

  4. Java Multithreading 6:Synchronized Lock code block (this And any object )

    One .Synchronized(this) Lock code block With keywords synchronized In some cases, the modification method has disadvantages , If it takes a long time to execute this method , Threads 1 When executing this method , Threads 2 You have to wait . In this case ...

  5. Java Multithreading - Sync :synchronized Communicating with threads : Producer consumer model

    Big guy had a good weekend , Xiaole comes to offer you a technological dinner . Last time I said Java Multithreading creation and state | Happy bytes , Next , Let's go on Java Multithreading - Sync :synchronized Communicating with threads : Producer consumer model . One . Same as ...

  6. Java Multithreading series --“JUC lock ”03 And Fair lock ( One )

    Summary This chapter is right “ Fair lock ” This paper introduces the lock acquisition mechanism of ( The fair lock in this paper refers to the fair lock of mutex ), The content includes : Basic concepts ReentrantLock Data structure reference code to get fair lock ( be based on JDK1.7.0_40) One . tryAcqu ...

  7. Java Multithreading series --“JUC lock ”01 And frame

    This chapter , Let's introduce the architecture of locks : Later chapters will analyze and introduce them one by one . Directory as follows :01. Java Multithreading series --“JUC lock ”01 And frame 02. Java Multithreading series --“JUC lock ”02 And The mutex Reentrant ...

  8. Java Multithreading series --“JUC lock ”06 And Condition Conditions

    Summary Front facing JUC The principle of the lock in the package is introduced , This chapter will JUC It is often used with lock Condition To introduce , The content includes :Condition Introduce Condition Function list Condition Please indicate the source of the reprint ...

  9. Java Multithreading series --“JUC lock ”05 And Not fair lock

    Summary The first two chapters analyze " Fair lock acquisition and release mechanism ", This chapter begins with a discussion of “ Not fair lock ” The acquisition lock of / Analyze the process of releasing the lock . The content includes : Refer to the code to get the unfair lock ( be based on JDK1.7.0_40) Release the unfair lock ( The base ...

Random recommendation

  1. AngularJs Entry form development

    What I share with you in this article is the essential part of front-end development AngularJs Basic knowledge of framework form development , Hope to use and learn AngularJs Help . 1. Simple form submission : 2. More form elements : 3. Initialize form : Code ...

  2. jQuery Easy to use web content printing plug-in

    A brief tutorial jQuery.print It is a simple and powerful webpage content printing jQuery plug-in unit . The webpage printing plug-in can print webpage elements in specified area , You can specify that certain elements will not be printed , You can also print the entire page . And it provides a wealth of ...

  3. Redmine Performance testing

    Redmine It's been deployed for a month , Feedback can be slow . 1. see log Find out , After the transaction is updated, send Email, If there is a problem connecting to the mail server , Will wait for overtime , It's very slow . 2. After solving the problem of sending mail , Still sometimes slow ,ActiveRe ...

  4. use PHP towards mysql Add data

    <?php $name=$_POST['name']; $gender = $_POST['gender']; $age=$_POST['age']; # Connect to database $link = mysql ...

  5. RMAN Restore directory

    Whether to use RMAN Restore directory (Recovery Catalog You may have heard it from other people or books RMAN Restore directory ( It could be some other name ,RMAN Recovery Catalog The translation of English is more complicated , Hereinafter referred to as the recovery directory ), ...

  6. sentinel build redis Summary of cluster experience

    One .protected-mode By default ,redis node and sentinel Of protected-mode All are yes, When building a cluster , If you want to connect remotely redis colony , Need to put redis node and se ...

  7. JVM Parameter configuration

    JVM Parameter configuration Set the heap size -Xms Initial heap size -Xmx Maximum heap size -Xmn Set younger generation size Set the stack size per thread -Xss Set the stack size for each thread Set younger generation size -XX:NewSize= -X ...

  8. Docker brief introduction ( turn )

    Docker Is an open source application container engine , Allows developers to package their applications and dependencies into a portable container , Then post to any popular  Linux  On the machine , You can also implement virtualization . Containers are completely sandboxed using the sandbox mechanism , There won't be any... Between each other ...

  9. Luogu U4704 function

    set up gcd(a,b) by a and b Maximum common divisor of ,xor(a,b) by a Exclusive or b Result . Title Description kkk Always put gcd It's written in xor. Today's math exam just came out gcd(a,b)=? Such a question , however kkk It's all understood as xor( ...

  10. I accumulated and wrote winfrom operation api class

    quote class using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys ...