当前位置: 首页 > news >正文

阿里计算机专业面试黄金宝典2

1. 如何实现并发编程

 

  • 定义

并发编程是指在同一时间段内,让多个任务可以同时执行的编程方式。在 Java 里,主要借助多线程机制达成并发编程,通过创建多个线程,让它们在同一进程中并行执行不同任务。线程作为 CPU 调度的最小单元,Java 提供了丰富的 API 用于创建、管理和控制线程。

  • 要点
  1. 线程创建:有继承 Thread 类、实现 Runnable 接口、实现 Callable 接口并结合 FutureTask 这三种方式。
  2. 线程同步:使用 synchronized 关键字、Lock 接口及其实现类,保证线程安全,防止多个线程同时访问共享资源引发数据不一致问题。
  3. 线程通信:利用 wait()notify() 和 notifyAll() 方法,或者 Condition 接口实现线程间协作。
  4. 线程池使用:借助 ExecutorService 管理线程生命周期,提升线程复用性与性能。

代码示例

import java.util.concurrent.*;

// 继承 Thread 类
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread running: " + Thread.currentThread().getName());
    }
}

// 实现 Runnable 接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable running: " + Thread.currentThread().getName());
    }
}

// 实现 Callable 接口
class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "Callable result: " + Thread.currentThread().getName();
    }
}

public class ConcurrencyExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 继承 Thread 类创建线程
        MyThread thread = new MyThread();
        thread.start();

        // 实现 Runnable 接口创建线程
        MyRunnable runnable = new MyRunnable();
        Thread runnableThread = new Thread(runnable);
        runnableThread.start();

        // 实现 Callable 接口创建线程
        MyCallable callable = new MyCallable();
        FutureTask<String> futureTask = new FutureTask<>(callable);
        Thread callableThread = new Thread(futureTask);
        callableThread.start();
        System.out.println(futureTask.get());

        // 使用线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(runnable);
        Future<String> future = executorService.submit(callable);
        System.out.println(future.get());
        executorService.shutdown();
    }
}    

 

  • 应用
  1. Web 服务器:处理大量并发的客户端请求,提高服务器响应能力。
  2. 大数据处理:并行处理大规模数据,提升数据处理效率。

 

2. Java 锁有哪些种类,有什么区别

 

  • 定义

Java 中的锁是用于控制多个线程对共享资源的访问,保障线程安全的机制。

  • 种类及区别
  • synchronized 锁
    1. 定义:基于对象头的 Mark Word 实现,属于 JVM 层面的锁。
    2. 特点:自动获取和释放锁,为非公平锁,支持可重入,适用于简单的同步场景。
  • ReentrantLock 锁
    1. 定义:基于 AQS(AbstractQueuedSynchronizer)实现,是 Java 语言层面的锁。
    2. 特点:需手动获取和释放锁,可实现公平锁和非公平锁,支持可重入,功能更灵活,适用于复杂的同步场景。
  • ReentrantReadWriteLock 锁
    1. 定义:基于 AQS 实现,将锁分为读锁和写锁。
    2. 特点:读锁可被多个线程同时持有,写锁为独占锁,适用于读多写少的场景。
  • StampedLock 锁
    1. 定义:JDK 8 引入的新锁,基于乐观读的思想。
    2. 特点:提供乐观读、悲观读和写锁三种模式,性能更高,适用于读多写少且对性能要求较高的场景。

代码示例

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

// 使用 synchronized 锁
class SynchronizedLockExample {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

// 使用 ReentrantLock 锁
class ReentrantLockExample {
    private int count = 0;
    private final Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        return count;
    }
}

// 使用 ReentrantReadWriteLock 锁
class ReentrantReadWriteLockExample {
    private int count = 0;
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();

    public void increment() {
        writeLock.lock();
        try {
            count++;
        } finally {
            writeLock.unlock();
        }
    }

    public int getCount() {
        readLock.lock();
        try {
            return count;
        } finally {
            readLock.unlock();
        }

相关文章:

  • Hadoop大数据平台部署(Hadoop3.2.4+Hive4.0.1)
  • RabbitMQ 深度解析:从基础到高级应用的全面指南
  • 使用 Axios 进行 API 请求与接口封装
  • 傲梅分区助手单文件版:无损分区管理工具
  • 正版金币捕鱼海洋管家APP源码结构解析与运行环境说明
  • 智慧酒店企业站官网-前端静态网站模板【前端练习项目】
  • 多线性读取数据实现QCustomPlot瀑布图
  • javaSE.抛出异常
  • 2025天梯赛 L2专项训练
  • 项目中引入 Redis 及 常用五种数据类型
  • Django:高效构建现代Web应用的利器
  • MAC Mini M4 上测试Detectron2 图像识别库
  • 青少年编程与数学 02-016 Python数据结构与算法 19课题、矩阵算法
  • colorful一词的常见中译
  • 模版初阶及STL简介
  • 快速入手K8s+Docker+KubeSphere+DevOps
  • 基于STM32、HAL库的MAX3109ETJ总线转UART驱动程序设计
  • Python 机器学习 第6章 机器学习的通用工作流程实例
  • RAG(Retrieval-Augmented Generation)召回算法是检索增强生成模型中的关键组件
  • 扩增子分析|基于R语言microeco包进行微生物群落网络分析(network网络、Zi-Pi关键物种和subnet子网络图)
  • 港理大公布多项AI+医工成果,助港建设国际医疗创新枢纽
  • 人社部:就业政策储备充足,将会根据形势变化及时推出
  • 上海质子重离子医院已收治8000例患者,基本覆盖国内常见恶性肿瘤
  • 学校食堂饭菜有蛆?举报人遭值班人员辱骂?四川苍溪县教育局回应
  • CSR周刊:李宁打造世界地球日特别活动,珀莱雅发布2024年度可持续发展报告
  • 张家界乒乓球公开赛设干部职级门槛引关注,回应:仅限嘉宾组