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/n/349516.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
COSKACOSKA
上一篇 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

发表回复

登录后才能评论