Java 17 Recipes
Download 3.2 Mb. Pdf ko'rish
|
Java 17 Recipes
- Bu sahifa navigatsiya:
- 10-10. Updating a Common Value Across Multiple Threads Problem
How It Works
AtomicLong (and its cousin AtomicInteger) are built to be used safely in concurrent environments. They have methods to atomically increment (and get) the changed value. Even if hundreds of threads call the AtomicLong increment() method, the returned value is unique. If you need to make decisions and update the variables, always use the atomic operations that AtomicLong offers; for example, compareAndSet. If not, your code is not thread-safe (as any check-then-act operation needs to be atomic) unless you externally protect the atomic reference by using your own locks. Changing a long value may be done in two memory write operations (as allowed by the Java Memory Model). Thus two threads could end up overlapping those two operations in what might appear to be thread-safe code. The result would be a completely unexpected (and likely wrong) long value. Chapter 10 ConCurrenCy 389 long counter = 0; public long incrementCounter() { return counter++; } Even though it looks like there is only one operation to increment the counter, in reality, there are two operations that occur at the machine-language level (a retrieve of the variable and then an increment). Two or more threads could obtain the same value since they both retrieve the variable but haven’t incremented it yet. Then all the threads increment the counter to the same number. 10-10. Updating a Common Value Across Multiple Threads Problem Your application needs to safely maintain a single summed value across multiple threads. Solution Utilize DoubleAdder or LongAdder to contain the value that is being summed across multiple threads to ensure safe handling. In the following example, two threads are adding values to DoubleAdder at the same time. In the end, the value is summed and displayed. public static void main(String[] args) { Recipe10_10 recipe10_10 = new Recipe10_10(); recipe10_10.start(); } DoubleAdder da = new DoubleAdder(); private void start() { Thread thread1 = new Thread(() -> { for (int i1 = 0; i1 < 10; i1++) { Chapter 10 ConCurrenCy 390 da.add(i1); System.out.println("Adding " + i1); } }); Thread thread2 = new Thread(() -> { for (int i1 = 0; i1 < 10; i1++) { da.add(i1); System.out.println("Adding " + i1); } }); thread1.start(); thread2.start(); try { System.out.println("Sleep while summing...."); Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("The sum is: " + da.doubleValue()); } } The following are the results. Adding 0 Adding 1 Adding 2 Adding 3 Adding 4 Adding 5 Adding 6 Adding 7 Adding 0 Adding 8 Adding 9 Adding 1 Chapter 10 ConCurrenCy 391 Adding 2 Adding 3 Adding 4 Adding 5 Adding 6 Adding 7 Adding 8 Adding 9 The sum is: 90.0 Download 3.2 Mb. Do'stlaringiz bilan baham: |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling