MST

星途 面试题库

面试题:Java中如何实现线程安全的队列之基础方式

在Java中,简单描述使用`Collections.synchronizedQueue`来实现线程安全队列的原理,并举例说明如何使用它创建一个线程安全的`Queue`,以及它在多线程环境下可能存在的性能问题。
19.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

原理

Collections.synchronizedQueue实现线程安全队列的原理是通过对队列的所有操作(如添加、移除、检查等)进行同步包装。它内部使用了一个对象锁,在对队列进行任何修改或读取操作时,都需要先获取该锁,从而保证同一时间只有一个线程可以访问队列,避免了多线程并发访问导致的数据不一致问题。

使用示例

import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.Collections;

public class SynchronizedQueueExample {
    public static void main(String[] args) {
        // 创建一个普通的Queue
        Queue<Integer> queue = new LinkedBlockingQueue<>();
        // 使用Collections.synchronizedQueue将其包装成线程安全的Queue
        Queue<Integer> synchronizedQueue = Collections.synchronizedQueue(queue);

        // 模拟多线程操作
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                synchronizedQueue.add(i);
                System.out.println("Produced: " + i);
            }
        });

        Thread consumer = new Thread(() -> {
            while (true) {
                Integer item = synchronizedQueue.poll();
                if (item != null) {
                    System.out.println("Consumed: " + item);
                } else {
                    break;
                }
            }
        });

        producer.start();
        consumer.start();

        try {
            producer.join();
            consumer.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

性能问题

  1. 竞争开销:由于所有操作都需要获取锁,当多个线程频繁访问队列时,锁的竞争会变得非常激烈,导致大量线程等待锁的释放,从而增加线程上下文切换的开销,降低系统整体性能。
  2. 串行化操作:因为同一时间只有一个线程能访问队列,使得原本可以并行执行的操作变成了串行执行,特别是在高并发环境下,这会成为性能瓶颈。例如,一个线程在执行队列的添加操作时,其他线程无论是想添加还是移除元素都必须等待,即使这些操作在逻辑上并不冲突。