Home Java javaTutorial Detailed explanation of thread safety and non-thread safety in Java

Detailed explanation of thread safety and non-thread safety in Java

Oct 12, 2017 am 10:09 AM
java about Safety

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(); 
  } 
}
Copy after login

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
Copy after login

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>();
Copy after login

in the test() method into


List<Object> list = new Vector<Object>();
Copy after login

and then run the program.

Output result:


100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
Copy after login

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++; 
  } 
}
Copy after login

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
Copy after login

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++; 
  } 
}
Copy after login

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
Copy after login

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 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)

Perfect Number in Java Perfect Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Smith Number in Java Smith Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

Create the Future: Java Programming for Absolute Beginners Create the Future: Java Programming for Absolute Beginners Oct 13, 2024 pm 01:32 PM

Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.

See all articles