Java并发编程 - 多线程/并发面试题集合(持续更新)

1. 现在有线程T1、T2和T3。你如何确保T2线程在T1之后执行,并且T3线程在T2之后执行。

https://www.cnblogs.com/helios-fz/p/11216925.html

2. Java 中新的Lock接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。

Lock接口的最大优势是它为读和写提供两个单独的锁(ReentrantReadWriteLock),ReentrantReadWriteLock的特点是:“读读共享”,“读写互斥”,“写写互斥”。(附:Lock取款机示例

高性能缓存简易示例:

public class ReadWriteMap {

    private final Map<Object, Object> map;
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock();
    private final Lock writeLock = lock.writeLock();

    public ReadWriteMap(Map<Object, Object> map) {
        this.map = map;
    }

    public Object put(Object key, Object value) {
        try {
            writeLock.lock();
            return map.put(key, value);
        } finally {
            writeLock.unlock();
        }
    }

    public Object get(Object key) {
        try {
            readLock.lock();
            return map.get(key);
        } finally {
            writeLock.unlock();
        }
    }
}

3.Java中wait和sleep方法有什么区别。

sleep() 是Thread类的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁(或监视器)依然保持。休眠时间结束后线程自动回到就绪状态。

wait() 是Object类的方法,调用此方法会让当前线程暂停执行指定的时间,并放弃对象锁进入等待池(wait pool)。只有调用对象的notify()或notifyAll()方法才能唤醒等待池中的线程进入等锁池(lockpool)。如果线程重新获得对象的锁就可以进入就绪状态。

wait()方法多用于线程间通信,而sleep()只是在执行时暂停。

4.如何在Java中实现一个阻塞队列。

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。
1)阻塞的插入:当队列满时,队列会阻塞插入元素的线程,直到队列不满。
2)阻塞的移除:当队列空时,队列会阻塞移除元素的线程,直到队列不空。

public class BlockingQueue {

    private final List<Object> queue = new LinkedList<>();
    private int capacity = 10;

    public BlockingQueue() {
    }

    public BlockingQueue(int capacity) {
        this.capacity = capacity;
    }

    public synchronized Object put(Object item) throws InterruptedException {
        while (queue.size() >= capacity) {
            wait();
        }
        queue.add(item);
        notifyAll();
        return item;
    }

    public synchronized void remove() throws InterruptedException {
        while (0 == queue.size()) {
            wait();
        }
        queue.remove(0);
        notifyAll();
    }

    public synchronized int getSize() {
        return queue.size();
    }
}

附:我在实现阻塞队列时遇到的一个问题 https://www.cnblogs.com/helios-fz/p/11721583.html

5.写一段死锁代码。说说你在Java中如何解决死锁。

https://www.cnblogs.com/helios-fz/p/11663518.html

6.Java中volatile关键字是什么。你如何使用它。它和Java中的同步方法有什么区别。

https://www.cnblogs.com/helios-fz/p/10935129.html

7.既然start()方法会调用run()方法,为什么我们调用 start() 方法,而不直接调用 run() 方法。

调用start()方法时,它会新建一个线程然后执行run()方法中的代码。

直接调用run()方法,则不会创建新线程,方法中的代码会在当前调用者的线程中执行。验证如下:

    public static void main(String[] args) throws InterruptedException {

        Thread thread1 = new Thread(() -> System.out.println(Thread.currentThread().getName()));
        Thread thread2 = new Thread(() -> System.out.println(Thread.currentThread().getName()));

        thread1.setName("thread1");
        thread1.start();

        Thread.sleep(1000);

        thread2.setName("thread2");
        thread2.run();
    }

8.什么是线程调度,Java中使用了什么线程调度方法。

线程调度是指按照特定机制为多个线程分配CPU的使用权。

一般的调度模型有两种:分时调度模型和抢占式调度模型。

  • 分时调度模型是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片。
  • 抢占式调度模型是指优先让可运行池中优先级高的线程占用CPU。如果可运行池中的线程优先级相同,那么就随机选择一个线程,使其占用CPU。处于运行状态的线程会一直运行,直至它不得不放弃CPU。

Java使用的是抢占式调度。

原文地址:https://www.cnblogs.com/helios-fz/p/11700320.html

时间: 2024-08-02 23:17:16

Java并发编程 - 多线程/并发面试题集合(持续更新)的相关文章

Java并发编程(8):多线程环境中安全使用集合API(含代码)

Java并发编程(8):多线程环境中安全使用集合API(含代码)JAVA大数据中高级架构 2018-11-09 14:44:47在集合API中,最初设计的Vector和Hashtable是多线程安全的.例如:对于Vector来说,用来添加和删除元素的方法是同步的.如果只有一个线程与Vector的实例交互,那么,要求获取和释放对象锁便是一种浪费,另外在不必要的时候如果滥用同步化,也有可能会带来死锁.因此,对于更改集合内容的方法,没有一个是同步化的.集合本质上是非多线程安全的,当多个线程与集合交互时

干货:Java并发编程必懂知识点解析(内附面试题)

本文大纲 1.并发编程三要素 原子性 原子,即一个不可再被分割的颗粒.在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败. 有序性 程序执行的顺序按照代码的先后顺序执行.(处理器可能会对指令进行重排序) 可见性 当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值. 2. 线程的五大状态 创建状态 当用 new 操作符创建一个线程的时候 就绪状态 调用 start 方法,处于就绪状态的线程并不一定马上就会执行 run 方法,还需要等待CPU的

Java并发编程、多线程、线程池…

Java多线程干货系列(1):Java多线程基础http://www.importnew.com/21136.html#comment-651146 40个Java多线程问题总结http://www.importnew.com/18459.html#comment-651217 Java线程面试题 Top 50http://www.importnew.com/12773.html Java并发编程:Thread类的使用http://www.cnblogs.com/dolphin0520/p/39

Java并发编程之多线程同步

线程安全就是防止某个对象或者值在多个线程中被修改而导致的数据不一致问题,因此我们就需要通过同步机制保证在同一时刻只有一个线程能够访问到该对象或数据,修改数据完毕之后,再将最新数据同步到主存中,使得其他线程都能够得到这个最新数据.下面我们就来了解Java一些基本的同步机制. Java提供了一种稍弱的同步机制即volatile变量,用来确保将变量的更新操作通知到其他线程.当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的.然而,在访问volatile变量时不会执行加锁操作

【多线程】Java并发编程:Lock(转载)

原文链接:http://www.cnblogs.com/dolphin0520/p/3923167.html Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock. 也许有朋友会问,既然都可以通过synchronized来实现同步访问了,那么为什么还需要提供Lock?这个问题将在下面进行阐述

Java并发编程笔记 并发概览

并发概览 >>同步 如何同步多个线程对共享资源的访问是多线程编程中最基本的问题之一.当多个线程并发访问共享数据时会出现数据处于计算中间状态或者不一致的问题,从而影响到程序的正确运行.我们通常把这种情况叫做竞争条件(race condition),把并发访问共享数据的代码叫做关键区域(critical section).同步就是使得多个线程顺序进入关键区域从而避免竞争条件的发生. >>线程安全性 编写线程安全的代码的核心是要对状态访问操作进行管理,尤其是对共享的和可变的状态访问. 线

JAVA并发编程J.U.C学习总结

前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www.cnblogs.com/chenpi/p/5614290.html 本文目录如下,基本上涵盖了J.U.C的主要内容: JSR 166及J.U.C Executor框架(线程池. Callable .Future) AbstractQueuedSynchronizer(AQS框架) Locks & C

【Java并发编程】并发编程大合集-值得收藏

http://blog.csdn.net/ns_code/article/details/17539599这个博主的关于java并发编程系列很不错,值得收藏. 为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列内容系列内容按照由浅入深的学习顺序总结如下,点击相应的标题即可跳转到对应的文章    [Java并发编程]实现多线程的两种方法    [Java并发编程]线程的中断    [Java并发编程]正确挂起.恢复.终止线程    [Java并发编程]守护线程和线程阻塞    [Ja

Java并发和多线程基础(一)

1.java线程状态 Java中的线程可以处于下列状态之一: NEW: 至今尚未启动的线程处于这种状态. RUNNABLE: 正在 Java 虚拟机中执行的线程处于这种状态. BLOCKED: 受阻塞并等待某个监视器锁的线程处于这种状态. WAITING: 无限期地等待另一个线程来执行某一特定操作的线程处于这种状态. TIMED_WAITING: 等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态. TERMINATED: 已退出的线程处于这种状态. 在给定时间点上,一个线程只能处于