MST

星途 面试题库

面试题:Java多线程在网络编程中的同步问题

在Java网络编程中,使用多线程时常常会遇到资源竞争问题。假设你有一个网络服务器程序,多个线程可能同时访问并修改共享资源,比如一个记录客户端连接数的计数器。请描述你会如何使用同步机制(如`synchronized`关键字、`ReentrantLock`等)来确保数据的一致性和线程安全,并给出简单示例代码。
32.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

使用 synchronized 关键字

  1. 原理synchronized 关键字可以修饰方法或代码块。当一个线程进入被 synchronized 修饰的方法或代码块时,它会自动获取对象的锁。其他线程在锁被释放之前无法进入该同步区域,从而保证同一时间只有一个线程能访问共享资源。
  2. 示例代码
public class Server {
    private int clientCount = 0;

    // 同步方法
    public synchronized void incrementClientCount() {
        clientCount++;
    }

    public synchronized int getClientCount() {
        return clientCount;
    }
}

在上述代码中,incrementClientCountgetClientCount 方法都被 synchronized 修饰,这样在多线程环境下,对 clientCount 的读写操作都是线程安全的。

使用 ReentrantLock

  1. 原理ReentrantLock 是一个可重入的互斥锁,它提供了比 synchronized 更灵活的锁控制。线程在进入临界区前需要调用 lock() 方法获取锁,在离开临界区时调用 unlock() 方法释放锁。
  2. 示例代码
import java.util.concurrent.locks.ReentrantLock;

public class ServerWithLock {
    private int clientCount = 0;
    private ReentrantLock lock = new ReentrantLock();

    public void incrementClientCount() {
        lock.lock();
        try {
            clientCount++;
        } finally {
            lock.unlock();
        }
    }

    public int getClientCount() {
        lock.lock();
        try {
            return clientCount;
        } finally {
            lock.unlock();
        }
    }
}

在上述代码中,通过 ReentrantLocklock()unlock() 方法来控制对 clientCount 的访问,确保线程安全。注意在 try - finally 块中释放锁,以保证即使出现异常,锁也能被正确释放。