search
HomeJavajavaTutorialDetailed explanation of thread safety and non-thread safety in Java

This article mainly introduces the analysis of Java thread safety and non-thread safety, involving the simulation of non-thread safety phenomena and the implementation of thread safety. Friends in need can refer to it and exchange and learn together.

What is the difference between ArrayList and Vector? What is the difference between HashMap and HashTable? What is the difference between StringBuilder and StringBuffer? These are common basic questions in Java interviews. Faced with such a question, the answer is: ArrayList is non-thread safe, Vector is thread safe; HashMap is non-thread safe, HashTable is thread safe; StringBuilder is non-thread safe, and StringBuffer is thread safe. Because this is what was written in the "Complete Java Interview Questions" I just memorized last night. At this point, if you continue to ask: What is thread safety? What is the difference between thread-safe and non-thread-safe? Under what circumstances are they used? Such a series of questions spurted out a lot of blood...

Non-thread-safe phenomenon simulation

Here we use ArrayList and Vector The reader will explain.

The following code creates a new non-thread-safe ArrayList in the main thread, and then opens 1000 threads to add elements to this ArrayList respectively. Each thread adds 100 elements, and so on for all threads. After execution is completed, what should be the size of this ArrayList? Should be 100,000?


public class Main 
{ 
  public static void main(String[] args) 
  { 
    // 进行10次测试 
    for(int i = 0; i < 10; i++) 
    { 
      test(); 
    } 
  } 
  public static void test() 
  { 
    // 用来测试的List 
    List<Object> list = new ArrayList<Object>(); 
    // 线程数量(1000) 
    int threadCount = 1000; 
    // 用来让主线程等待threadCount个子线程执行完毕 
    CountDownLatch countDownLatch = new CountDownLatch(threadCount); 
    // 启动threadCount个子线程 
    for(int i = 0; i < threadCount; i++) 
    { 
      Thread thread = new Thread(new MyThread(list, countDownLatch)); 
      thread.start(); 
    } 
    try 
    { 
      // 主线程等待所有子线程执行完成,再向下执行 
      countDownLatch.await(); 
    } 
    catch (InterruptedException e) 
    { 
      e.printStackTrace(); 
    } 
    // List的size 
    System.out.println(list.size()); 
  } 
} 
class MyThread implements Runnable 
{ 
  private List<Object> list; 
  private CountDownLatch countDownLatch; 
  public MyThread(List<Object> list, CountDownLatch countDownLatch) 
  { 
    this.list = list; 
    this.countDownLatch = countDownLatch; 
  } 
  public void run() 
  { 
    // 每个线程向List中添加100个元素 
    for(int i = 0; i < 100; i++) 
    { 
      list.add(new Object()); 
    } 
    // 完成一个子线程 
    countDownLatch.countDown(); 
  } 
}

The above was tested 10 times (why test 10 times? Because non-thread safety does not cause problems every time).

Output result:


99946
100000
100000
100000
99998
99959
100000
99975
100000
99996

The above output result shows that not every test result is 100000, there are several times At the end of the test, the size of the ArrayList was less than 100000, and an IndexOutOfBoundsException was even thrown from time to time. (If this phenomenon does not occur, you can try a few more times)

This is a problem caused by non-thread safety. If the above code is used in a production environment, there will be hidden dangers and bugs.

Then use the thread-safe Vector to test. Change the above code in one place, change


List<Object> list = new ArrayList<Object>();

in the test() method into


List<Object> list = new Vector<Object>();

and then run the program.

Output result:


100000
100000
100000
100000
100000
100000
100000
100000
100000
100000

After running a few more times, I found that they were all 100000, without any problems. Because Vector is thread-safe, there will be no problems when multiple threads operate on the same Vector object.

Try changing to LinkedList again. Similar problems with ArrayList will also occur, because LinkedList is also not thread-safe.

How to choose between the two

Non-thread safety means that problems may occur when multiple threads operate the same object. Thread safety means that there will be no problem when multiple threads operate the same object.

Thread safety must use many synchronized keywords for synchronization control, so it will inevitably lead to a reduction in performance.

So when using it, if multiple threads operate the same object, use the thread-safe Vector; otherwise, use the more efficient ArrayList.

Non-thread safety!=Unsafe

Someone has an incorrect view during use: I The program is multi-threaded and cannot use ArrayList. It is safe to use Vector.

Non-thread safety does not mean that it cannot be used in a multi-threaded environment. Note what I said above: multiple threads operate on the same object. Note that it is the same object. For example, the top simulation is a new ArrayList in the main thread and then multiple threads operate the same ArrayList object.

If it is a new ArrayList in each thread, and this ArrayList is only used in this thread, then there is definitely no problem.

Thread safety implementation

Thread safety is achieved through thread synchronization control, which is the synchronized keyword .

Here, I used code to implement a non-thread-safe counter and a thread-safe counter Counter, and conducted multi-thread tests on them.

Non-thread-safe counter:


public class Main 
{ 
  public static void main(String[] args) 
  { 
    // 进行10次测试 
    for(int i = 0; i < 10; i++) 
    { 
      test(); 
    } 
  } 
  public static void test() 
  { 
    // 计数器 
    Counter counter = new Counter(); 
    // 线程数量(1000) 
    int threadCount = 1000; 
    // 用来让主线程等待threadCount个子线程执行完毕 
    CountDownLatch countDownLatch = new CountDownLatch(threadCount); 
    // 启动threadCount个子线程 
    for(int i = 0; i < threadCount; i++) 
    { 
      Thread thread = new Thread(new MyThread(counter, countDownLatch)); 
      thread.start(); 
    } 
    try 
    { 
      // 主线程等待所有子线程执行完成,再向下执行 
      countDownLatch.await(); 
    } 
    catch (InterruptedException e) 
    { 
      e.printStackTrace(); 
    } 
    // 计数器的值 
    System.out.println(counter.getCount()); 
  } 
} 
class MyThread implements Runnable 
{ 
  private Counter counter; 
  private CountDownLatch countDownLatch; 
  public MyThread(Counter counter, CountDownLatch countDownLatch) 
  { 
    this.counter = counter; 
    this.countDownLatch = countDownLatch; 
  } 
  public void run() 
  { 
    // 每个线程向Counter中进行10000次累加 
    for(int i = 0; i < 10000; i++) 
    { 
      counter.addCount(); 
    } 
    // 完成一个子线程 
    countDownLatch.countDown(); 
  } 
} 
class Counter 
{ 
  private int count = 0; 
  public int getCount() 
  { 
    return count; 
  } 
  public void addCount() 
  { 
    count++; 
  } 
}

In the above test code, 1000 threads are opened, and each thread controls the counter After 10,000 accumulations, the final output result should be 10,000,000.

But the Counter in the above code is not controlled synchronously, so it is not thread-safe.

Output result:


9963727
9973178
9999577
9987650
9988734
9988665
9987820
9990847
9992305
9972233

Slightly modify the Counter into a thread-safe counter:


class Counter 
{ 
  private int count = 0; 
  public int getCount() 
  { 
    return count; 
  } 
  public synchronized void addCount() 
  { 
    count++; 
  } 
}

The above just adds synchronized synchronization control to the addCount() method, and it becomes a thread-safe counter. Execute the program again.

Output results:


10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000

Summary

The above is the detailed content of Detailed explanation of thread safety and non-thread safety in Java. For more information, please follow other related articles on the PHP Chinese website!

Statement
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
How does node.next = node; in Java AQS source code help with garbage collection?How does node.next = node; in Java AQS source code help with garbage collection?Apr 19, 2025 pm 02:27 PM

cancelAcquire method in JavaAQS source code: node.next=node;...

Ultimate consistency in distributed systems: how to apply and how to compensate for data inconsistencies?Ultimate consistency in distributed systems: how to apply and how to compensate for data inconsistencies?Apr 19, 2025 pm 02:24 PM

Exploring the application of ultimate consistency in distributed systems Distributed transaction processing has always been a problem in distributed system architecture. To solve the problem...

What is the reason why the browser does not respond after the WebSocket server returns 401? How to solve it?What is the reason why the browser does not respond after the WebSocket server returns 401? How to solve it?Apr 19, 2025 pm 02:21 PM

The browser's unresponsive method after the WebSocket server returns 401. When using Netty to develop a WebSocket server, you often encounter the need to verify the token. �...

When Tomcat loads Spring-Web modules, does the SPI mechanism really destroy the visibility principle of Java class loaders?When Tomcat loads Spring-Web modules, does the SPI mechanism really destroy the visibility principle of Java class loaders?Apr 19, 2025 pm 02:18 PM

Analysis of class loading behavior of SPI mechanism when Tomcat loads Spring-Web modules. Tomcat is used to discover and use the Servle provided by Spring-Web when loading Spring-Web modules...

How to choose Java project management tools when learning back-end development?How to choose Java project management tools when learning back-end development?Apr 19, 2025 pm 02:15 PM

Confused with choosing Java project management tools for beginners. For those who are just beginning to learn backend development, choosing the right project management tools is crucial...

How to implement monitoring events? A comprehensive analysis from principle to practiceHow to implement monitoring events? A comprehensive analysis from principle to practiceApr 19, 2025 pm 02:12 PM

Regarding the implementation principles and methods of listening events In programming, listening to events is a common requirement, especially listening for changes in a certain value. Many people may...

How to dynamically modify the savePath parameter of @Excel annotation in easypoi when project starts in Java?How to dynamically modify the savePath parameter of @Excel annotation in easypoi when project starts in Java?Apr 19, 2025 pm 02:09 PM

How to dynamically configure the parameters of entity class annotations in Java During the development process, we often encounter the need to dynamically configure the annotation parameters according to different environments...

Why does the Python script not be found when submitting a PyFlink job on YARN?Why does the Python script not be found when submitting a PyFlink job on YARN?Apr 19, 2025 pm 02:06 PM

Analysis of the reason why Python script cannot be found when submitting a PyFlink job on YARN When you try to submit a PyFlink job through YARN, you may encounter...

See all articles

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

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.