works:programmer:java:thread-safe
Содержание
Потоки и переменные
Использование volatile - не безопастно к потокам
import static java.lang.System.out; import java.util.Collection; import java.util.LinkedList; public class EntryPoint { private volatile int counter = 0; class ChildThread extends Thread { public void run() { for (int i=0; i<1000; i++) { counter++; } } } public EntryPoint() throws InterruptedException { Collection<Thread> threads = new LinkedList<Thread>(); for (int i=0; i<100; i++ ) { Thread th = new ChildThread(); threads.add(th); th.start(); } for (Thread thread : threads) { thread.join(); } out.println("Done!"); out.println(String.format("Now counter == %d", counter)); } public static void main(String []args) throws InterruptedException { var ep = new EntryPoint(); } }
java -cp /tmp/WkigqTFpnD EntryPoint Done! Now counter == 97533
Использование Atomic - безопастно к потокам
import static java.lang.System.out; import java.util.Collection; import java.util.LinkedList; import java.util.concurrent.atomic.AtomicInteger; public class EntryPoint { private AtomicInteger counter = new AtomicInteger(0); class ChildThread extends Thread { public void run() { for (int i=0; i<1000; i++) { counter.addAndGet(1); } } } public EntryPoint() throws InterruptedException { Collection<Thread> threads = new LinkedList<Thread>(); for (int i=0; i<100; i++ ) { Thread th = new ChildThread(); threads.add(th); th.start(); } for (Thread thread : threads) { thread.join(); } out.println("Done!"); out.println(String.format("Now counter == %d", counter.get())); } public static void main(String []args) throws InterruptedException { var ep = new EntryPoint(); } }
java -cp /tmp/WkigqTFpnD EntryPoint Done! Now counter == 100000
Использование synchronized - безопастно к потокам
Интересное замечание, создание простых synchronized функций создают гораздо меньше байткода.
import static java.lang.System.out; import java.util.Collection; import java.util.LinkedList; public class EntryPoint { private int counter = 0; private synchronized void increment() { // Синхронизированная функция, меньше байткода this.counter++; } private void increment2() { // Синхронизированный блок synchronized(EntryPoint.class) { counter++; }; } class ChildThread extends Thread { public void run() { for (int i=0; i<1000; i++) { increment2(); // И `increment` и `increment2` создают одинаковый результат } } } public EntryPoint() throws InterruptedException { Collection<Thread> threads = new LinkedList<Thread>(); for (int i=0; i<100; i++ ) { Thread th = new ChildThread(); threads.add(th); th.start(); } for (Thread thread : threads) { thread.join(); } out.println("Done!"); out.println(String.format("Now counter == %d", counter)); } public static void main(String []args) throws InterruptedException { var ep = new EntryPoint(); } }
java -cp /tmp/WkigqTFpnD EntryPoint Done! Now counter == 100000
works/programmer/java/thread-safe.txt · Последнее изменение: 2021/07/15 12:08 — 127.0.0.1