阿里面试题分享(二)

简介: synchronized与wait()和nitofy()/notifyAll()方法相结合可以实现等待/通知模型,ReentrantLock同样可以,但是需要借助Condition,且Condition有更好的灵活性,

题目描述:


使用“生产者-消费者模式”编写代码实现:线程A随机间隔(10~200ms)按顺序生成1到100的数字(共100个),放到某个队列中。

线程B、C、D即时消费这些数据:

  • 线程B消费所有被3整除的数,
  • 线程C消费所有被5整除的数,
  • 其它的由线程D进行消费。

线程BCD消费这些数据时在控制台中打印出来,

要求按顺序打印这些数据。限时40分钟,可以查API


这里有一个网友的答案:


我的答案:


package com.oho.alg;
import java.util.PrimitiveIterator.OfLong;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import lombok.SneakyThrows;
public class Producer implements Runnable {
  private BlockingQueue<Integer> queue;
  private OfLong longs = new Random().longs(10, 200).iterator();
  public Producer(BlockingQueue<Integer> queue) {
    this.queue = queue;
  }
  @SneakyThrows
  @Override
  public void run() {
    for (int i = 1; i <= 100; i++) {
      queue.put(i);
      System.out.println("生产了:" + i);
      try {
        TimeUnit.MILLISECONDS.sleep(longs.nextLong());
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}
package com.oho.alg;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Consumer {
  private Lock lock = new ReentrantLock();
  private Condition cc3 = lock.newCondition();
  private Condition cc5 = lock.newCondition();
  private Condition ccn = lock.newCondition();
  private BlockingQueue<Integer> queue;
  public Consumer(BlockingQueue<Integer> queue) {
    this.queue = queue;
  }
  public void c3() {
    try {
      lock.lock();
      while (true) {
        if (queue.peek() != null) {
          while (queue.peek() % 3 != 0) {
            cc3.await();
          }
          System.out.println("消费3的倍数: " + queue.poll());
          cc5.signal();
          ccn.signal();
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
  public void c5() {
    try {
      lock.lock();
      while (true) {
        if (queue.peek() != null) {
          while (queue.peek() % 5 != 0) {
            cc5.await();
          }
          System.out.println("消费5的倍数: " + queue.poll());
          cc3.signal();
          ccn.signal();
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
  public void other() {
    try {
      lock.lock();
      while (true) {
        if (queue.peek() != null) {
          while (queue.peek() % 3 == 0 || queue.peek() % 5 == 0) {
            ccn.await();
          }
          System.out.println("消费other倍数: " + queue.poll());
          cc3.signal();
          cc5.signal();
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
  public static void main(String[] args) throws InterruptedException {
    ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(100);
    Consumer consumer = new Consumer(queue);
    new Thread(new Producer(queue)).start();
    new Thread(() -> consumer.c3()).start();
    new Thread(() -> consumer.c5()).start();
    new Thread(() -> consumer.other()).start();
  }
}


这题看起来挺简单的,但实际写的时候还是有一些点需要注意,尤其是对condition的使用。


7.png


synchronized与wait()和nitofy()/notifyAll()方法相结合可以实现等待/通知模型,ReentrantLock同样可以,但是需要借助Condition,且Condition有更好的灵活性,具体体现在:


1、一个Lock里面可以创建多个Condition实例,实现多路通知


2、notify()方法进行通知时,被通知的线程是Java虚拟机随机选择的,但是ReentrantLock结合Condition可以实现有选择性地通知,这是非常重要的



相关文章
|
1月前
|
Python 开发工具
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
|
1月前
|
机器学习/深度学习 Python 算法
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
最新【Python 百练成钢】时间调整、二进制数、回文素数、字母距离(1),2024年最新2024年阿里Python岗面试必问
|
1月前
|
数据采集 SQL 数据挖掘
2024年8个Python高效数据分析的技巧_python 数据分析 效率,2024年最新阿里社招p7面试几轮
2024年8个Python高效数据分析的技巧_python 数据分析 效率,2024年最新阿里社招p7面试几轮
|
1月前
|
PHP Python
最新【Python】 实现循环最快的方式_python while循环加速,2024年最新阿里php面试题
最新【Python】 实现循环最快的方式_python while循环加速,2024年最新阿里php面试题
|
1月前
|
算法 Java 应用服务中间件
阿里面试:说说自适应限流?
限流想必大家都不陌生,它是一种控制资源访问速率的策略,用于保护系统免受过载和崩溃的风险。限流可以控制某个服务、接口或系统在一段时间内能够处理的请求或数据量,以防止系统资源耗尽、性能下降或服务不可用。 常见的限流策略有以下几种: 1. **令牌桶算法**:基于令牌桶的方式,限制每个单位时间内允许通过的请求量,请求量超出限制的将被拒绝或等待。 2. **漏桶算法**:基于漏桶的方式,限制系统处理请求的速率,请求速率过快时将被限制或拒绝。 3. **计数器算法**:通过计数器记录单位时间内的请求次数,并根据设定的阈值进行限制。 通过合理的限流策略,可以保护系统免受恶意攻击、突发流量和资源
34 4
阿里面试:说说自适应限流?
|
3天前
【年前最后一波装逼】记一次阿里面试,我是如何用一行代码解决约瑟夫环问题的
【年前最后一波装逼】记一次阿里面试,我是如何用一行代码解决约瑟夫环问题的
|
1月前
|
应用服务中间件 网络安全 数据安全/隐私保护
Sqlmap参数设置_sqlmap怎么指定参数(1),阿里面试100%会问到的网络安全
Sqlmap参数设置_sqlmap怎么指定参数(1),阿里面试100%会问到的网络安全
|
1月前
|
SQL 分布式计算 前端开发
2024年最全用python写一个自动生成春联的软件,打包exe,2024年最新阿里p8面试题和答案
2024年最全用python写一个自动生成春联的软件,打包exe,2024年最新阿里p8面试题和答案
2024年最全用python写一个自动生成春联的软件,打包exe,2024年最新阿里p8面试题和答案
|
1月前
|
Python
2024年最新【Python从零到壹】Python模块介绍与使用(1),2024年最新阿里面试场景题
2024年最新【Python从零到壹】Python模块介绍与使用(1),2024年最新阿里面试场景题
2024年最新【Python从零到壹】Python模块介绍与使用(1),2024年最新阿里面试场景题
|
1月前
|
数据采集 数据安全/隐私保护 Python
2024年最新【Python】如何用Python来操作PDF文件,收藏(2),2024年最新阿里p7Python面试题
2024年最新【Python】如何用Python来操作PDF文件,收藏(2),2024年最新阿里p7Python面试题
2024年最新【Python】如何用Python来操作PDF文件,收藏(2),2024年最新阿里p7Python面试题