Isu dan penyelesaian keselamatan thread biasa dalam pembangunan Java
Dalam pembangunan Java, multi-threading ialah konsep yang sangat biasa dan penting . Walau bagaimanapun, pelbagai benang sering membawa beberapa siri isu keselamatan benang. Isu keselamatan benang merujuk kepada ralat data, ralat logik dan isu lain yang mungkin berlaku apabila berbilang benang mengakses sumber dikongsi pada masa yang sama. Artikel ini akan memperkenalkan beberapa isu keselamatan urutan biasa dan menyediakan penyelesaian yang sepadan, bersama-sama dengan contoh kod.
Penyelesaian 1: Gunakan kata kunci yang disegerakkan
Dengan menggunakan kata kunci yang disegerakkan pada segmen kod utama, anda boleh memastikan bahawa hanya satu utas boleh melaksanakan segmen kod pada masa yang sama , dengan itu mengelakkan isu keadaan Perlumbaan.
Contoh kod:
class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
Penyelesaian 2: Gunakan antara muka Kunci
Menggunakan antara muka Kunci boleh memberikan penguncian yang lebih halus Berbanding dengan antara muka Kunci yang disegerakkan adalah lebih fleksibel.
Contoh kod:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Counter { private int count = 0; private Lock lock = new ReentrantLock(); public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } public int getCount() { return count; } }
Terdapat dua cara utama untuk mengelakkan kebuntuan:
Yang pertama adalah untuk mengelakkan kebergantungan bulat; mencipta benang secara individu Kolam boleh menguruskan kitaran hayat benang dan mengelakkan kebuntuan.
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class Resource { private final Object lock1 = new Object(); private final Object lock2 = new Object(); public void methodA() { synchronized (lock1) { synchronized (lock2) { // do something } } } public void methodB() { synchronized (lock2) { synchronized (lock1) { // do something } } } } public class Main { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(2); Resource resource = new Resource(); executorService.submit(() -> resource.methodA()); executorService.submit(() -> resource.methodB()); executorService.shutdown(); } }
Kaedah wait() boleh membuat thread semasa menunggu, dan kaedah notify() boleh bangun benang yang menunggu.
class SharedResource { private int value; private boolean isValueSet = false; public synchronized void setValue(int value) { while (isValueSet) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.value = value; isValueSet = true; notify(); } public synchronized int getValue() { while (!isValueSet) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } isValueSet = false; notify(); return value; } } public class Main { public static void main(String[] args) { SharedResource sharedResource = new SharedResource(); Thread producer = new Thread(() -> { for (int i = 0; i < 10; i++) { sharedResource.setValue(i); System.out.println("Producer produces: " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread consumer = new Thread(() -> { for (int i = 0; i < 10; i++) { int value = sharedResource.getValue(); System.out.println("Consumer consumes: " + value); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); producer.start(); consumer.start(); } }
Atas ialah kandungan terperinci Isu dan penyelesaian keselamatan benang biasa dalam pembangunan Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!