Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Performance and Challenges | Multithreading Basics
Multithreading in Java
course content

Зміст курсу

Multithreading in Java

Multithreading in Java

1. Multithreading Basics
2. Synchronized Collections
3. High-level Synchronization Mechanisms
4. Multithreading Best Practices

Performance and Challenges

Performance Measurement

You can use the nanoTime() or System.currentTimeMillis() methods to measure the execution time of multithreaded code.

Note

In this video, the code compares the performance of multi-threaded and single-threaded summation of array elements in Java. It initializes an array with random integers, distributes the task among multiple threads to compute the sum in parallel, and then performs the same summation sequentially to measure and compare execution times.

Data Races

Race conditions occur in multithreaded programs when two or more threads simultaneously attempt to operate on a shared resource without proper synchronization. This can lead to unpredictable and incorrect program behavior because the results depend on how threads execute in parallel and how quickly they access the shared resource.

This issue was discussed in the previous section, where it was shown how to solve the problem using the synchronized keyword.

Unpredictable Behavior

Unpredictable behavior can arise from improper synchronization. For instance, lack of synchronization may lead to threads working with outdated data.

In this video, the code demonstrates the issue of unpredictable behavior in multithreaded applications caused by unsynchronized shared state access.

Decision

This issue can be addressed by using the volatile keyword. A variable declared as volatile can be modified by multiple threads simultaneously. This guarantees that the value of the variable will be immediately visible to all other threads after the change.

But you don't need to declare all fields with volatile

Variables declared as volatile are synchronized with main memory on every read and write access. This means that when one thread updates the value of a volatile variable, the change is immediately visible to all other threads, enhancing visibility. However, this also means that reads might be slower, so use volatile only when necessary.

Deadlock

Deadlock happens when two or more threads become stuck waiting for each other to release resources.

In the video, we encountered deadlock when two threads simultaneously locked the monitors of objects in different sequences, leading to a situation where the threads simply waited for each other to release the monitors they needed.

To resolve this issue, we need to ensure that such situations don't occur. We can achieve this by making sure all threads lock the monitors of objects in the same order.

In this case, the first thread that locks an object's monitor will prevent other threads from locking that same monitor, forcing them to wait until the first thread completes its task. Only after the first thread finishes will it release the monitor, allowing other threads to proceed.

Avoiding Multithreading Problems

Data synchronization: Use the synchronized keyword for methods and code blocks to prevent data races.

Avoid mutual locking: Ensure that all threads acquire resources in the same order.

1. Which method is used to measure code execution time in nanoseconds?
2. What is the name of the problem when multiple threads simultaneously try to modify the same resource?

Which method is used to measure code execution time in nanoseconds?

Виберіть правильну відповідь

What is the name of the problem when multiple threads simultaneously try to modify the same resource?

Виберіть правильну відповідь

Все було зрозуміло?

Секція 1. Розділ 5
We're sorry to hear that something went wrong. What happened?
some-alt