Java JUC面試題解析

一、JUC相關概念

Java JUC(j.u.c)表示Java並發編程工具包,是Java SE 5.0提供的線程處理API中最重要的一個,它主要位於java.util.concurrent包中。JUC中包含了許多工具類,可以讓我們更加方便地進行多線程開發。下面我們來詳細介紹幾個與JUC相關的概念。

1.1 原子性

原子性指的是一個操作是不可分割的,也就是說在進行這個操作時,不存在其他的線程同時在進行同樣的操作。Java中提供了一些原子性的操作類,常見的有AtomicInteger、AtomicBoolean等,它們可以保證操作的原子性,從而避免了線程安全問題。

public class AtomicIntegerTest {
    private static AtomicInteger count = new AtomicInteger();
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i  {
                for (int j = 0; j < 10; j++) {
                    System.out.println(count.incrementAndGet());
                }
            });
        }
        executor.shutdown();
    }
}

1.2 可見性

可見性指的是當一個線程對共享變數進行了修改後,其他線程能夠立即看到這個修改。Java中通過volatile關鍵字來實現可見性。

public class VolatileVariableTest {
    private static volatile boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            while (!flag) {}
            System.out.println("Flag has been changed to true.");
        }).start();
        Thread.sleep(1000);
        flag = true;
        System.out.println("Flag has been set to true.");
    }
}

1.3 有序性

有序性指的是在並發情況下,程序的執行結果與理論預期的結果是一致的。Java中可以通過synchronized關鍵字或ReentrantLock類來實現有序性。

public class SynchronizedTest {
    private static int count = 0;
    public static synchronized void increase() {
        count++;
    }
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i  {
                for (int j = 0; j < 10; j++) {
                    increase();
                }
            });
        }
        executor.shutdown();
        while (!executor.isTerminated()) {}
        System.out.println(count);
    }
}

二、JUC的重要組件

Java JUC包含了很多重要的組件,這些組件可以讓我們更加方便地進行多線程開發。下面我們來介紹JUC中比較重要的幾個組件。

2.1 Semaphore

Semaphore是一個計數信號量,用於控制同時訪問某個資源的線程數量。例如,有一個任務需要保證最多只能有5個線程同時執行,那麼我們可以通過Semaphore來實現。

public class SemaphoreTest {
    private static Semaphore semaphore = new Semaphore(5);
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i  {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " is using the resource.");
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + " has released the resource.");
                }
            });
        }
        executor.shutdown();
    }
}

2.2 CountDownLatch

CountDownLatch是一個同步工具類,它可以讓某個線程等待特定的一組操作完成後再繼續執行。例如,我們可以讓主線程等待10個子線程全部執行完畢後再繼續執行。

public class CountDownLatchTest {
    private static CountDownLatch latch = new CountDownLatch(10);
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i  {
                try {
                    System.out.println(Thread.currentThread().getName() + " is executing.");
                    Thread.sleep(500);
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        latch.await();
        System.out.println("All threads have finished executing.");
        executor.shutdown();
    }
}

2.3 CyclicBarrier

CyclicBarrier是另一個同步工具類,它可以讓一組線程互相等待,直到到達某個屏障點後再一起繼續執行。例如,我們可以讓10個線程分別執行不同的任務,然後在某個節點處等待,等待所有線程都到達之後再繼續執行。

public class CyclicBarrierTest {
    private static CyclicBarrier barrier = new CyclicBarrier(10);
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i  {
                try {
                    System.out.println(Thread.currentThread().getName() + " is executing.");
                    Thread.sleep(500);
                    barrier.await();
                    System.out.println(Thread.currentThread().getName() + " continues executing.");
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
        }
        executor.shutdown();
    }
}

三、JUC中的線程安全容器

Java JUC包含了很多線程安全容器,它們可以讓我們在多線程環境下更加安全地進行元素的添加、刪除和讀取。下面我們來介紹JUC中比較重要的幾個線程安全容器。

3.1 ConcurrentHashMap

ConcurrentHashMap是一個支持高並發、線程安全的HashMap,它內部使用了分段鎖機制,可以保證並發訪問的安全性和效率。

public class ConcurrentHashMapTest {
    private static ConcurrentHashMap map = new ConcurrentHashMap();
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i  {
                for (int j = 0; j < 10; j++) {
                    map.put(UUID.randomUUID().toString(), j);
                }
            });
        }
        executor.shutdown();
        while (!executor.isTerminated()) {}
        System.out.println(map.size());
    }
}

3.2 CopyOnWriteArrayList

CopyOnWriteArrayList是一個支持高並發、線程安全的List,它內部使用了一種叫做「寫時複製」的機制,寫操作時會先複製出一個新的List進行操作,操作完成後再將原List指針指向新的List。因為讀操作不需要加鎖,所以它的讀操作速度比較快,但寫操作則比較慢。

public class CopyOnWriteArrayListTest {
    private static CopyOnWriteArrayList list = new CopyOnWriteArrayList();
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i  {
                for (int j = 0; j < 10; j++) {
                    list.add(UUID.randomUUID().toString());
                }
            });
        }
        executor.shutdown();
        while (!executor.isTerminated()) {}
        System.out.println(list.size());
    }
}

3.3 BlockingQueue

BlockingQueue是一個支持阻塞的隊列,在多線程環境下可以讓生產者線程和消費者線程更加安全地進行交互。BlockingQueue提供了一些常用的實現類,例如ArrayBlockingQueue、LinkedBlockingQueue等。

public class BlockingQueueTest {
    private static BlockingQueue queue = new LinkedBlockingQueue();
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(() -> {
            try {
                for (int i = 0; i  {
            try {
                while (true) {
                    String element = queue.take();
                    System.out.println(element);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        executor.shutdown();
    }
}

原創文章,作者:COSKA,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/349516.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
COSKA的頭像COSKA
上一篇 2025-02-15 17:10
下一篇 2025-02-15 17:10

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論