cause

Stroll 【 Blog Garden - Bo asked 】 Found an interesting question :

Question link :https://q.cnblogs.com/q/140032/

This code looks like this :

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class AutomicityTest implements Runnable { private int i = 0; public int getValue() {
return i;
} /**
* Synchronization method , Add 2
*/
public synchronized void evenIncrement() {
i += 2;
// i++;
// i++;
} @Override
public void run() {
while (true) {
evenIncrement();
}
} public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); // AutomicityTest Threads
AutomicityTest automicityTest = new AutomicityTest();
exec.execute(automicityTest); // main Threads
while (true) {
int value = automicityTest.getValue();
if (value % 2 != 0) {
System.out.println(value);
System.exit(0);
}
}
}
}

The code is simple ( At first I didn't see the problem clearly , It is also suggested that the landlord learn Java grammar , An embarrassing bunch of ~~~)

Simply explain the code logic

One 、AutomicityTest Class implements the Runnable Interface , And implement run() Method ,run() One of the methods is while(true) loop , A... Is called in the loop body synchronized The method of decoration evenIncrement();

Two 、AutomicityTest There is one in the class int i Member variables ;

3、 ... and 、 stay main() Method uses a thread pool to execute threads ( direct new Thread().start() It's the same ), then while(true) Member variables are printed continuously in the loop body i Value , If it is an odd number, exit the virtual machine .

What do you think this code will output ?

Yes, it's a dead cycle !!!

Here comes the interesting place , If I put the synchronization method evenIncrement() Change to the following :

public synchronized void evenIncrement() {
// i += 2;
i++;
i++;
}

As a result, the virtual machine exits !!!

Are you wondering , If you don't wonder , There's no need to look down >_<

Let's analyze

1. Start with the method entry ,main() Method AutomicityTest Threads and In itself main() Where main Threads , therefore AutomicityTest A thread is a write thread ,main A thread is a read thread , Since there is reading and writing , Multiple threads again , It involves working memory and main memory model , I won't repeat it here .

2. Write thread yes synchronized Embellished , But the read thread does not , This leads to inconsistent reading and writing , The solution is to give getValue() add synchronized, At this point, the execution result is normal

3. But the problem is not over , Why? i += 2 Dead cycle , and 【 Two article 】 i++ But quit the virtual machine ?

Bytecode level analysis

public synchronized void evenIncrement() {
i += 2;
} // The corresponding bytecode
public synchronized void evenIncrement();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: dup
2: getfield #2 // Field i:I
5: iconst_2
6: iadd
7: putfield #2 // Field i:I
10: return
public synchronized void evenIncrement() {
i++;
i++;
} // The corresponding bytecode
public synchronized void evenIncrement();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: dup
2: getfield #2 // Field i:I
5: iconst_1
6: iadd
7: putfield #2 // Field i:I
10: aload_0
11: dup
12: getfield #2 // Field i:I
15: iconst_1
16: iadd
17: putfield #2 // Field i:I
20: return

i+=2;

Bytecode instructions have only one segment putfield, No execution is even , Even numbers are executed , So there will be a dead cycle .

i++; i++;

Bytecode instructions have two segments putfield, Because before getValue() No addition synchronized, Then in execution getValue() When ,putfield May not be implemented , It may have been executed once , It may have been executed twice , No execution is even , Execution once is an odd number , Execution twice is even ; Again because AutomicityTest Threads run() yes while (true) {} Of , So it can always execute to an odd number , Exit virtual machine .

Last

This is the end of the analysis , So the key to this problem is that the write operation is atomic , But the read operation is not , The data read out is not final .

synchronized Under the i+=2 and i++ i++ More related articles with different execution results

  1. Built in lock ( Two )synchronized Wait for notification mechanism under

    One . wait for / Introduction to the notification mechanism Collaboration between threads :    In order to complete a task , Threads need to collaborate , The way : interrupt . Mutually exclusive , And the suspension of threads above mutual exclusion . Wake up the : Such as : Generator -- Consumer model . Or a certain action is completed , Can wake up the next ...

  2. solve Chrome Safari Opera In the environment Dynamically create iframe onload Events are executed synchronously

    Let's look at the following code first : setTimeout(function(){ alert(count); },2000); var count = []; document.body.appendChild(c ...

  3. Linux Get the current directory under , The following commands are to be executed : $(cd `dirname $0`;pwd)

    Linux Get the current directory under , The following commands are to be executed : $(cd `dirname $0`;pwd) among ,   dirname $0, Gets the parent directory of the currently executing script file       cd `dirname $0` ...

  4. mac Find all files of the same type in the current directory , And execute the command line

    With TexturePacker give an example MAC Next use TexturePacker The command line packages all the *.tps file 1. Good configuration tps The file needs to be configured with a path . Parameters, etc. .( You can also not configure , Use the command line to implement . Specific reference :ht ...

  5. ASP.NET MVC Asynchronous under Action Definition and implementation principle of

    One . Request processing based on thread pool ASP.NET Through the mechanism of thread pool to deal with concurrent HTTP request . One Web A thread pool is maintained inside the application , When an incoming request for this application is detected , A free thread will be obtained from the pool to process the request . When it's done , ...

  6. linux Next /etc/profile、~/.bash_profile ~/.profile Implementation process of

    About logging in linux when ,/etc/profile.~/.bash_profile And so on . In the login Linux The procedure to execute the file is as follows : Just signed in Linux when , First start /etc/profile ...

  7. linux Next source、sh、bash、./ The difference between executing scripts

    Original address :http://blog.csdn.net/caesarzou/article/details/7310201 source Command usage : source FileName effect : At present bash Environmental Science ...

  8. window10 Under the eclipse use java Connect hadoop perform mapreduce Mission

    One . preparation 1.eclipse Connect hadoop Plug in for , Version matching required , Here are a few common 2 Version of plug-in hadoop2x-eclipse-plugin-master password :feg1 2.hadoop-c ...

  9. mybatis Next use log4j Print sql Statements and execution results

    Reprinted from :https://www.cnblogs.com/jeevan/p/3493972.html I thought it was a very simple question , As a result, I still couldn't do it for a long time ; then google, baidu, Search out various methods ...

  10. Loadrunner:win10 Next Vuser Run the script through ,Controller Execute user concurrent error report

    The phenomenon :win7 install LR It can be used normally. , take win7 Upgrade to win10 after , An error is reported after running the scenario :Error (-81024): LR_VUG: The 'QTWeb' type is not supported ...

Random recommendation

  1. java Time comparison in China

    package com.newtouch.test; import java.text.SimpleDateFormat;import java.util.Date; public class Tim ...

  2. In depth analysis ENode Internal implementation process and idempotent design in key places

    ENode 2.0 - In depth analysis ENode Internal implementation process and idempotent design in key places Preface ENode Architecture diagram ENode Process analysis is implemented inside the framework Command Idempotent processing of Domain Event Concurrent flushing during persistence ...

  3. linux Command synthesis

    Find the specified string in the file and highlight : find .|xargs grep --color=auto "hello" dos The lookup : netstat -ano|findstr &quo ...

  4. solr- Summary of problems during construction and use - link

    The following errors can be identified in CDH edition Hbase colony +Lily hbase indexer+solrCloud Can be solved in the environment of , If there are successful cases of open source version solution, please comment below . 1.If you see this err ...

  5. Redis Non relational database

    1. brief introduction Redis It's a memory based Key-Value Non relational database , from C Language writing . Redis As a distributed caching framework . Distributed SESSION Separate . The implementation of distributed lock and so on . Redis The reason for the speed : ...

  6. mysql Use navicat and mysqldump Derived data

    1.navicat Mode one : Select the table , Right click to dump :( Contains table structure and data ) Mode two : Select the tool in the upper right corner , Click data transfer , Select the database on the right side of this page , Select file on the left . Click next , Select the exported table name and various functions , And then click ...

  7. DSO windowed optimization Code (1)

    I don't want to explain how marginalize, What is? First-Estimates Jacobian (FEJ). Just look at the code here , have a look Hessian How the matrix is constructed . 1 Optimize the process The whole optimization process , also ...

  8. Asp.Net WebApi Service creation

    Web API A kind of REST Architecture style Web service . So-called REST Architecture has nothing to do with technology , It is a kind of software architecture design oriented to resources . WCF since 3.5 After that, it also provides a pair of REST Style support , But and WebAPI To make it seem more cumbersome ,We ...

  9. python call .net Dynamic library

    # python call .net Dynamic library ### pythonnet brief introduction ------------------------------ pythonnet yes cpython An extension of - pythonnet Provides cp ...

  10. linux $* [email protected] Specific location parameters

    For example : The script name is test.sh There are three : 1 2 3 function test.sh 1 2 3 after $* by "1 2 3"( Wrapped in quotation marks )[email protected] by "1" "2&qu ...