Home Java javaTutorial How to solve inter-thread communication and data sharing issues in Java

How to solve inter-thread communication and data sharing issues in Java

Oct 08, 2023 am 10:37 AM
Thread communication: wait and notify Data sharing: synchronized keyword volatile keyword

How to solve inter-thread communication and data sharing issues in Java

How to solve the problem of inter-thread communication and data sharing in Java

In Java, inter-thread communication and data sharing are important parts of realizing multi-threaded programming. In order for multiple threads to safely access shared data and communicate effectively, we need to use some mechanism to ensure the order and data consistency between threads. This article will introduce several common inter-thread communication and data sharing solutions in Java and provide corresponding code examples.

1. Use the synchronized keyword to implement inter-thread communication and data sharing

  1. Use the synchronized method

The synchronized keyword can modify the method so that there is only one Threads can enter this method for execution, and other threads need to wait. This can be used to implement communication and data sharing between threads.

Sample code:

public class ThreadCommunication {
    private boolean flag = false;

    public synchronized void printNumbers() {
        // 线程A负责打印奇数
        for (int i = 1; i <= 10; i += 2) {
            while (flag) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("ThreadA: " + i);
            flag = true;
            notifyAll();
        }
    }

    public synchronized void printLetters() {
        // 线程B负责打印偶数
        for (char c = 'A'; c <= 'J'; c += 2) {
            while (!flag) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("ThreadB: " + c);
            flag = false;
            notifyAll();
        }
    }

    public static void main(String[] args) {
        final ThreadCommunication communication = new ThreadCommunication();

        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printNumbers();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printLetters();
            }
        });

        threadA.start();
        threadB.start();
    }
}
Copy after login

In the above example, by using the synchronized keyword to modify the printNumbers() and printLetters() methods, the order and shared data between thread A and thread B are ensured consistency. Use the flag flag to control the alternate execution of two threads, and use the wait() and notifyAll() methods to perform thread mutual exclusion and communication.

  1. Use synchronized block

The synchronized keyword can also modify the code block so that only one thread can enter the code block for execution, and other threads need to wait. This can be used to implement communication and data sharing between threads.

Sample code:

public class ThreadCommunication2 {
    private Object lock = new Object();
    private int number = 0;

    public void printNumbers() {
        synchronized (lock) {
            // 线程A负责打印奇数
            for (int i = 1; i <= 10; i += 2) {
                while (number % 2 == 0) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("ThreadA: " + i);
                number++;
                lock.notifyAll();
            }
        }
    }

    public void printLetters() {
        synchronized (lock) {
            // 线程B负责打印偶数
            for (char c = 'A'; c <= 'J'; c += 2) {
                while (number % 2 != 0) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("ThreadB: " + c);
                number++;
                lock.notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        final ThreadCommunication2 communication = new ThreadCommunication2();

        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printNumbers();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printLetters();
            }
        });

        threadA.start();
        threadB.start();
    }
}
Copy after login

In the above example, by using the synchronized keyword to modify the code block, the consistency of the order and shared data between thread A and thread B is ensured. Use number variables and lock objects to control the alternate execution of two threads, and use the wait() and notifyAll() methods to perform thread mutual exclusion and communication.

2. Use Lock and Condition to realize inter-thread communication and data sharing

  1. Use ReentrantLock and Condition

ReentrantLock is reentrant provided by Java Mutex locks can be used to implement communication and data sharing between threads. Condition is a condition object provided by ReentrantLock, which can block and wake up threads through its await() and signalAll() methods.

Sample code:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadCommunication3 {
    private Lock lock = new ReentrantLock();
    private Condition numberCondition = lock.newCondition();
    private Condition letterCondition = lock.newCondition();
    private int number = 0;

    public void printNumbers() {
        lock.lock();
        try {
            // 线程A负责打印奇数
            for (int i = 1; i <= 10; i += 2) {
                while (number % 2 == 0) {
                    try {
                        numberCondition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("ThreadA: " + i);
                number++;
                letterCondition.signalAll();
            }
        } finally {
            lock.unlock();
        }
    }

    public void printLetters() {
        lock.lock();
        try {
            // 线程B负责打印偶数
            for (char c = 'A'; c <= 'J'; c += 2) {
                while (number % 2 != 0) {
                    try {
                        letterCondition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("ThreadB: " + c);
                number++;
                numberCondition.signalAll();
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        final ThreadCommunication3 communication = new ThreadCommunication3();

        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printNumbers();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printLetters();
            }
        });

        threadA.start();
        threadB.start();
    }
}
Copy after login

In the above example, the consistency of the order and shared data between thread A and thread B is achieved by using ReentrantLock and Condition. Use number variables, lock objects, and Condition objects to control the alternate execution of two threads, and block and wake up threads through the await() and signalAll() methods.

3. Use volatile keyword to realize data sharing between threads

The volatile keyword can be used to modify variables to ensure the visibility of variables to all threads. When one thread modifies the value of a volatile variable, other threads will immediately see the latest value, thus ensuring data consistency.

Sample code:

public class ThreadCommunication4 {
    private volatile boolean flag = false;

    public void printNumbers() {
        // 线程A负责打印奇数
        for (int i = 1; i <= 10; i += 2) {
            while (flag) {
                // 空循环,等待flag为false
            }
            System.out.println("ThreadA: " + i);
            flag = true;
        }
    }

    public void printLetters() {
        // 线程B负责打印偶数
        for (char c = 'A'; c <= 'J'; c += 2) {
            while (!flag) {
                // 空循环,等待flag为true
            }
            System.out.println("ThreadB: " + c);
            flag = false;
        }
    }

    public static void main(String[] args) {
        final ThreadCommunication4 communication = new ThreadCommunication4();

        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printNumbers();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                communication.printLetters();
            }
        });

        threadA.start();
        threadB.start();
    }
}
Copy after login

In the above example, by using the volatile keyword to modify the flag variable, the consistency of the shared data between thread A and thread B is achieved. Use the flag variable to control the alternate execution of the two threads, and wait for the value of the flag through an empty loop.

Summary:

This article introduces several common solutions to solve inter-thread communication and data sharing problems in Java, including using the synchronized keyword and Lock and Condition to implement inter-thread communication, and using The volatile keyword implements data sharing. All of the above solutions can ensure the order and data consistency between multiple threads. Which solution to choose depends on the specific needs and scenarios. In actual multi-thread programming, it is necessary to choose an appropriate solution according to the specific situation to solve the problem of inter-thread communication and data sharing, so as to ensure the correctness and performance of the program.

The above is the detailed content of How to solve inter-thread communication and data sharing issues in 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

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.

Undress AI Tool

Undress AI Tool

Undress images for free

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)

Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Apr 19, 2025 pm 04:51 PM

Troubleshooting and solutions to the company's security software that causes some applications to not function properly. Many companies will deploy security software in order to ensure internal network security. ...

How to simplify field mapping issues in system docking using MapStruct? How to simplify field mapping issues in system docking using MapStruct? Apr 19, 2025 pm 06:21 PM

Field mapping processing in system docking often encounters a difficult problem when performing system docking: how to effectively map the interface fields of system A...

How to elegantly obtain entity class variable names to build database query conditions? How to elegantly obtain entity class variable names to build database query conditions? Apr 19, 2025 pm 11:42 PM

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

How do I convert names to numbers to implement sorting and maintain consistency in groups? How do I convert names to numbers to implement sorting and maintain consistency in groups? Apr 19, 2025 pm 11:30 PM

Solutions to convert names to numbers to implement sorting In many application scenarios, users may need to sort in groups, especially in one...

How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? Apr 19, 2025 pm 11:45 PM

Start Spring using IntelliJIDEAUltimate version...

How to safely convert Java objects to arrays? How to safely convert Java objects to arrays? Apr 19, 2025 pm 11:33 PM

Conversion of Java Objects and Arrays: In-depth discussion of the risks and correct methods of cast type conversion Many Java beginners will encounter the conversion of an object into an array...

How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? Apr 19, 2025 pm 09:51 PM

When using TKMyBatis for database queries, how to gracefully get entity class variable names to build query conditions is a common problem. This article will pin...

E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? Apr 19, 2025 pm 11:27 PM

Detailed explanation of the design of SKU and SPU tables on e-commerce platforms This article will discuss the database design issues of SKU and SPU in e-commerce platforms, especially how to deal with user-defined sales...

See all articles