亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Home Java Javagetting Started How to synchronize Java

How to synchronize Java

Nov 12, 2019 pm 05:59 PM
java Synchronize

How to synchronize Java

Why synchronization is required

Java allows multi-thread concurrency control. When multiple threads operate a shared Resource variables (such as addition, deletion, modification and query of data) will lead to inaccurate data and conflicts with each other. Therefore, a synchronization lock is added to avoid being called by other threads before the thread completes the operation, thereby ensuring that the thread Uniqueness and accuracy of variables.

1. Example

For example, if a bank account is operated by two threads at the same time, one takes 100 yuan and the other deposits 100 yuan. Assume that the account originally has 0 blocks. If the withdrawal thread and the deposit thread occur at the same time, what will happen? The withdrawal was unsuccessful and the account balance is 100. The withdrawal was successful and the account balance is 0. But which balance corresponds to which? It's hard to tell clearly, so the problem of multi-thread synchronization arises.

2. Situation without synchronization

For example, if a bank account is operated by two threads at the same time, one takes 100 yuan and the other deposits 100 yuan. . Assume that the account originally has 0 blocks. If the withdrawal thread and the deposit thread occur at the same time, what will happen? If the money withdrawal is unsuccessful, the account balance is 100. If the money withdrawal is successful, the account balance is 0. But which balance corresponds to which? It's hard to tell clearly, so the problem of multi-thread synchronization arises.

public class Bank {
   private int count =0;//賬戶余額
   
   //存錢(qián)
   public  void addMoney(int money){
       count +=money;
       System.out.println(System.currentTimeMillis()+"存進(jìn):"+money);
   }
    
    //取錢(qián)
    public  void subMoney(int money){
        if(count-money < 0){
            System.out.println("余額不足");
            return;
        }
        count -=money;
        System.out.println(+System.currentTimeMillis()+"取出:"+money);
    }
    
    //查詢
    public void lookMoney(){
        System.out.println("賬戶余額:"+count);
    }
}
package threadTest;
public class SyncThreadTest {
public static void main(String args[]){
final Bank bank=new Bank();
Thread tadd=new Thread(new Runnable() {
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            bank.addMoney(100);
            bank.lookMoney();
            System.out.println("\n");
            
        }
    }
});
Thread tsub = new Thread(new Runnable() {
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            bank.subMoney(100);
            bank.lookMoney();
            System.out.println("\n");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }    
        }
    }
});
tsub.start();
tadd.start();
}
}

Run result:

1502542307917取出:100
賬號(hào)余額:100
1502542308917存進(jìn):100
1502542308917取出:100
賬號(hào)余額:0
賬號(hào)余額:0
1502542309917存進(jìn):100
賬號(hào)余額:0
1502542309917取出:100
賬號(hào)余額:0

A non-thread safety problem occurs at this time, because two threads access an unsynchronized method at the same time. If these two threads operate instances in the business object at the same time, variables, non-thread safety issues may occur.

Solution: Just add the synchronized keyword in front of public void run().

3. Synchronization method

synchronized keyword modification method

There is a synchronized keyword modification method. Since every object in Java has a built-in lock, when a method is modified with this keyword, the built-in lock will protect the entire method. Before calling this method, you need to obtain the built-in lock, otherwise it will be blocked.

Code such as:

public synchronized void save(){}

Note: The synchronized keyword can also modify static methods. If the static method is called at this time, the entire class will be locked.

public class Bank {
private int count =0;//賬戶余額
//存錢(qián)
public  synchronized void addMoney(int money){
count +=money;
System.out.println(System.currentTimeMillis()+"存進(jìn):"+money);
}
//取錢(qián)
public  synchronized void subMoney(int money){
if(count-money < 0){
    System.out.println("余額不足");
    return;
}
count -=money;
System.out.println(+System.currentTimeMillis()+"取出:"+money);
}
//查詢
public void lookMoney(){
System.out.println("賬戶余額:"+count);
}
}

Run result:

余額不足
賬號(hào)余額:0
1502543814934存進(jìn):100
賬號(hào)余額:100
1502543815934存進(jìn):100
賬號(hào)余額:200
1502543815934取出:100
賬號(hào)余額:100

Thread synchronization is achieved in this way

Synchronization code block

That is, modified by the synchronized keyword block of statements.

The statement block modified by this keyword will automatically be added with a built-in lock to achieve synchronization

Code such as:

synchronized(object){ 
}

Note: Synchronization is a high-cost method operation, so synchronized content should be minimized.

Usually there is no need to synchronize the entire method, just use synchronized code blocks to synchronize key codes.

public class Bank {
private int count =0;//賬戶余額
//存錢(qián)
public  void addMoney(int money){
synchronized (this) {
    count +=money;
}
System.out.println(System.currentTimeMillis()+"存進(jìn):"+money);
}
//取錢(qián)
public   void subMoney(int money){
synchronized (this) {
    if(count-money < 0){
        System.out.println("余額不足");
        return;
    }
    count -=money;
}
System.out.println(+System.currentTimeMillis()+"取出:"+money);
}
//查詢
public void lookMoney(){
System.out.println("賬戶余額:"+count);
}
}

The running results are as follows:

余額不足
賬戶余額:0
余額不足
賬戶余額:100
1502544966411存進(jìn):100
賬戶余額:100
1502544967411存進(jìn):100
賬戶余額:100
1502544967411取出:100
賬戶余額:100
1502544968422取出:100

This also achieves thread synchronization, and the operating efficiency is higher than method synchronization. Synchronization is a high-cost operation, so synchronization should be minimized. Content. Usually there is no need to synchronize the entire method, just use synchronized code blocks to synchronize key code.

Use special domain variables (volatile) to achieve thread synchronization

a. The volatile keyword provides a lock-free mechanism for access to member variables;

b. Using volatile to modify member variables is equivalent to telling the virtual machine that the field may be updated by other threads;

c. Therefore, each time the member variable is used, it must be recalculated instead of using the value in the register. Value;

d.volatile does not provide any atomic operations, nor can it be used to modify final type variables.

Bank.java code is as follows:

package com.thread.demo;
/**
* Created by HJS on 2017/8/12.
*/
public class Bank {
private volatile int count =0;//賬戶余額
//存錢(qián)
public  void addMoney(int money){
synchronized (this) {
    count +=money;
}
System.out.println(System.currentTimeMillis()+"存進(jìn):"+money);
}
//取錢(qián)
public   void subMoney(int money){
synchronized (this) {
    if(count-money < 0){
        System.out.println("余額不足");
        return;
    }
    count -=money;
}
System.out.println(+System.currentTimeMillis()+"取出:"+money);
}
//查詢
public void lookMoney(){
System.out.println("賬戶余額:"+count);
}
}

Running result:

余額不足
賬戶余額:0
余額不足
賬戶余額:100
1502546287474存進(jìn):100
賬戶余額:100
1502546288474存進(jìn):100
1502546288474取出:100
賬戶余額:100

At this time, the order is messed up again, indicating that there is another synchronization problem, because volatile cannot guarantee atomic operations. Caused by this, volatile cannot replace synchronized. In addition, volatile will prevent the compiler from optimizing the code, so if you can't use it, don't apply it. Its principle is that every time a thread wants to access a volatile-modified variable, it reads it from the memory instead of reading it from the cache, so the variable value accessed by each thread is the same. This ensures synchronization.

Using reentrancy locks to achieve thread synchronization

A new java.util.concurrent package has been added in JavaSE5.0 to support synchronization. The ReentrantLock class is a reentrant, mutually exclusive lock that implements the Lock interface. It has the same basic behavior and semantics as using synchronized methods and blocks, and extends its capabilities.

Commonly used methods of the ReenreantLock class are:

ReentrantLock(): Create a ReentrantLock instance

lock(): Obtain the lock

unlock(): Release Lock

Note: ReentrantLock() also has a construction method that can create a fair lock, but it is not recommended because it can greatly reduce the running efficiency of the program.

Bank.java code is modified as follows:

public class Bank {
private  int count = 0;// 賬戶余額
//需要聲明這個(gè)鎖
private Lock lock = new ReentrantLock();
// 存錢(qián)
public void addMoney(int money) {
lock.lock();//上鎖
try{
    count += money;
    System.out.println(System.currentTimeMillis() + "存進(jìn):" + money);
}finally{
    lock.unlock();//解鎖
}
}
// 取錢(qián)
public void subMoney(int money) {
lock.lock();
try{
    if (count - money < 0) {
        System.out.println("余額不足");
        return;
    }
    count -= money;
    System.out.println(+System.currentTimeMillis() + "取出:" + money);
}finally{
    lock.unlock();
}
}
// 查詢
public void lookMoney() {
System.out.println("賬戶余額:" + count);
}
}

Running result:

余額不足
賬戶余額:0
1502547439892存進(jìn):100
賬戶余額:100
1502547440892存進(jìn):100
賬戶余額:200
1502547440892取出:100
賬戶余額:100

Note: Regarding the selection of Lock object and synchronized keyword:

a. It is best to use neither of them, and use a mechanism provided by the java.util.concurrent package to help users handle all lock-related code.

b.如果synchronized關(guān)鍵字能滿足用戶的需求,就用synchronized,因?yàn)樗芎?jiǎn)化代碼。

c.如果需要更高級(jí)的功能,就用ReentrantLock類(lèi),此時(shí)要注意及時(shí)釋放鎖,否則會(huì)出現(xiàn)死鎖,通常在finally代碼釋放鎖 。

使用局部變量實(shí)現(xiàn)線程同步

代碼如下:

public class Bank {
private static ThreadLocal<Integer> count = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue() {
    // TODO Auto-generated method stub
    return 0;
}
};
// 存錢(qián)
public void addMoney(int money) {
count.set(count.get()+money);
System.out.println(System.currentTimeMillis() + "存進(jìn):" + money);
}
// 取錢(qián)
public void subMoney(int money) {
if (count.get() - money < 0) {
    System.out.println("余額不足");
    return;
}
count.set(count.get()- money);
System.out.println(+System.currentTimeMillis() + "取出:" + money);
}
// 查詢
public void lookMoney() {
System.out.println("賬戶余額:" + count.get());
}
}

運(yùn)行結(jié)果如下:

復(fù)制代碼
余額不足
賬戶余額:0
余額不足
1502547748383存進(jìn):100
賬戶余額:100
賬戶余額:0
余額不足
賬戶余額:0
1502547749383存進(jìn):100
賬戶余額:200

看了運(yùn)行效果,一開(kāi)始一頭霧水,怎么只讓存,不讓取啊?看看ThreadLocal的原理:

如果使用ThreadLocal管理變量,則每一個(gè)使用該變量的線程都獲得該變量的副本,副本之間相互獨(dú)立,這樣每一個(gè)線程都可以隨意修改自己的變量副本,而不會(huì)對(duì)其他線程產(chǎn)生影響?,F(xiàn)在明白了吧,原來(lái)每個(gè)線程運(yùn)行的都是一個(gè)副本,也就是說(shuō)存錢(qián)和取錢(qián)是兩個(gè)賬戶,知識(shí)名字相同而已。所以就會(huì)發(fā)生上面的效果。

ThreadLocal 類(lèi)的常用方法

ThreadLocal() : 創(chuàng)建一個(gè)線程本地變量? ? ?

get() : 返回此線程局部變量的當(dāng)前線程副本中的值? ? ?

initialValue() : 返回此線程局部變量的當(dāng)前線程的"初始值"? ? ?

set(T value) : 將此線程局部變量的當(dāng)前線程副本中的值設(shè)置為value

注:ThreadLocal與同步機(jī)制

a.ThreadLocal與同步機(jī)制都是為了解決多線程中相同變量的訪問(wèn)沖突問(wèn)題。?

b.前者采用以"空間換時(shí)間"的方法,后者采用以"時(shí)間換空間"的方式。

php中文網(wǎng),大量的免費(fèi)Java入門(mén)教程,歡迎在線學(xué)習(xí)!

The above is the detailed content of How to synchronize Java. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1488
72
VSCode settings.json location VSCode settings.json location Aug 01, 2025 am 06:12 AM

The settings.json file is located in the user-level or workspace-level path and is used to customize VSCode settings. 1. User-level path: Windows is C:\Users\\AppData\Roaming\Code\User\settings.json, macOS is /Users//Library/ApplicationSupport/Code/User/settings.json, Linux is /home//.config/Code/User/settings.json; 2. Workspace-level path: .vscode/settings in the project root directory

How to handle transactions in Java with JDBC? How to handle transactions in Java with JDBC? Aug 02, 2025 pm 12:29 PM

To correctly handle JDBC transactions, you must first turn off the automatic commit mode, then perform multiple operations, and finally commit or rollback according to the results; 1. Call conn.setAutoCommit(false) to start the transaction; 2. Execute multiple SQL operations, such as INSERT and UPDATE; 3. Call conn.commit() if all operations are successful, and call conn.rollback() if an exception occurs to ensure data consistency; at the same time, try-with-resources should be used to manage resources, properly handle exceptions and close connections to avoid connection leakage; in addition, it is recommended to use connection pools and set save points to achieve partial rollback, and keep transactions as short as possible to improve performance.

Mastering Dependency Injection in Java with Spring and Guice Mastering Dependency Injection in Java with Spring and Guice Aug 01, 2025 am 05:53 AM

DependencyInjection(DI)isadesignpatternwhereobjectsreceivedependenciesexternally,promotingloosecouplingandeasiertestingthroughconstructor,setter,orfieldinjection.2.SpringFrameworkusesannotationslike@Component,@Service,and@AutowiredwithJava-basedconfi

How to work with Calendar in Java? How to work with Calendar in Java? Aug 02, 2025 am 02:38 AM

Use classes in the java.time package to replace the old Date and Calendar classes; 2. Get the current date and time through LocalDate, LocalDateTime and LocalTime; 3. Create a specific date and time using the of() method; 4. Use the plus/minus method to immutably increase and decrease the time; 5. Use ZonedDateTime and ZoneId to process the time zone; 6. Format and parse date strings through DateTimeFormatter; 7. Use Instant to be compatible with the old date types when necessary; date processing in modern Java should give priority to using java.timeAPI, which provides clear, immutable and linear

Understanding the Java Virtual Machine (JVM) Internals Understanding the Java Virtual Machine (JVM) Internals Aug 01, 2025 am 06:31 AM

TheJVMenablesJava’s"writeonce,runanywhere"capabilitybyexecutingbytecodethroughfourmaincomponents:1.TheClassLoaderSubsystemloads,links,andinitializes.classfilesusingbootstrap,extension,andapplicationclassloaders,ensuringsecureandlazyclassloa

Google Chrome cannot open local files Google Chrome cannot open local files Aug 01, 2025 am 05:24 AM

ChromecanopenlocalfileslikeHTMLandPDFsbyusing"Openfile"ordraggingthemintothebrowser;ensuretheaddressstartswithfile:///;2.SecurityrestrictionsblockAJAX,localStorage,andcross-folderaccessonfile://;usealocalserverlikepython-mhttp.server8000tor

Comparing Java Frameworks: Spring Boot vs Quarkus vs Micronaut Comparing Java Frameworks: Spring Boot vs Quarkus vs Micronaut Aug 04, 2025 pm 12:48 PM

Pre-formanceTartuptimeMoryusage, Quarkusandmicronautleadduetocompile-Timeprocessingandgraalvsupport, Withquarkusoftenperforminglightbetterine ServerLess scenarios.2.Thyvelopecosyste,

Understanding Network Ports and Firewalls Understanding Network Ports and Firewalls Aug 01, 2025 am 06:40 AM

Networkportsandfirewallsworktogethertoenablecommunicationwhileensuringsecurity.1.Networkportsarevirtualendpointsnumbered0–65535,withwell-knownportslike80(HTTP),443(HTTPS),22(SSH),and25(SMTP)identifyingspecificservices.2.PortsoperateoverTCP(reliable,c

See all articles