ITPub博客

首页 > 大数据 > 数据挖掘 > 好程序员分享同一资源多线程并发访问时的完整性

好程序员分享同一资源多线程并发访问时的完整性

原创 数据挖掘 作者:好程序员IT 时间:2019-09-29 16:23:30 0 删除 编辑

   好程序员面试题分享 同一资源多线程并发访问时的完整性 , 常用的同步方法是采用信号或加锁机制,确保资源在任意时刻至多被一个线程访问。Java 语言在多线程编程上实现了完全对象化,提供了对同步机制的良好支持。

 

  在Java 中一共有四种方法支持同步,其中前三个是同步方法,一个是管道方法。管道方法不建议使用,阻塞队列方法在问题 4 已有描述,现只提供前两种实现方法。

 

  - wait()/notify() 方法

 

  - await()/signal() 方法

 

  - BlockingQueue 阻塞队列方法

 

  - PipedInputStream/PipedOutputStream

 

  一、生产者类:

 

  ```

 

  public class Producer extends Thread { // 每次生产的产品数量

 

  private int num;

 

  // 所在放置的仓库

 

  private Storage storage;

 

  // 构造函数,设置仓库

 

  public Producer(Storage storage) {

 

  this.storage = storage;

 

  }

 

  // 线程 run 函数

 

  public void run() {

 

  produce(num);

 

  }

 

  // 调用仓库 Storage 的生产函数

 

  public void produce(int num) {

 

  storage.produce(num);

 

  }

 

  public int getNum() {

 

  return num;

 

  }

 

  public void setNum(int num) {

 

  this.num = num;

 

  }

 

  public Storage getStorage() {

 

  return storage;

 

  }

 

  public void setStorage(Storage storage) {

 

  this.storage = storage;

 

  }

 

  }

 

  ```

 

  二、消费者类:

 

  ```

 

  public class Consumer extends Thread { // 每次消费的产品数量

 

  private int num;

 

  // 所在放置的仓库

 

  private Storage storage;

 

  // 构造函数,设置仓库

 

  public Consumer(Storage storage) {

 

  this.storage = storage;

 

  }

 

  // 线程 run 函数

 

  public void run() {

 

  consume(num);

 

  }

 

  // 调用仓库 Storage 的生产函数

 

  public void consume(int num) {

 

  storage.consume(num);

 

  }

 

  // get/set 方法

 

  public int getNum() {

 

  return num;

 

  }

 

  public void setNum(int num) {

 

  this.num = num;

 

  }

 

  public Storage getStorage() {

 

  return storage;

 

  }

 

  public void setStorage(Storage storage) {

 

  this.storage = storage;

 

  }

 

  }

 

  ```

 

  仓库类:(wait()/notify() 方法 )

 

  ```

 

  public class Storage { // 仓库最大存储量

 

  private final int MAX_SIZE = 100;

 

  // 仓库存储的载体

 

  private LinkedList list = new LinkedList();

 

  // 生产 num 个产品

 

  public void produce(int num) {

 

  // 同步代码段

 

  synchronized (list) {

 

  // 如果仓库剩余容量不足

 

  while (list.size() + num > MAX_SIZE) {

 

  System.out.print(" 【要生产的产品数量】 :" + num);

 

  System.out.println(" 【库存量】 :" + list.size() + " 暂时不能执行生产任务 !");

 

  try {

 

  list.wait();// 由于条件不满足,生产阻塞

 

  } catch (InterruptedException e) {

 

  e.printStackTrace();

 

  }

 

  }

 

  // 生产条件满足情况下,生产 num 个产品

 

  for (int i = 1; i <= num; ++i) {

 

  list.add(new Object());

 

  }

 

  System.out.print(" 【已经生产产品数】 :" + num);

 

  System.out.println(" 【现仓储量为】 :" + list.size());

 

  list.notifyAll();

 

  }

 

  }

 

  // 消费 num 个产品

 

  public void consume(int num) {

 

  // 同步代码段

 

  synchronized (list) {

 

  // 如果仓库存储量不足

 

  while (list.size() < num) {

 

  System.out.print(" 【要消费的产品数量】 :" + num);

 

  System.out.println(" 【库存量】 :" + list.size() + " 暂时不能执行生产任务 !");

 

  try {

 

  // 由于条件不满足,消费阻塞

 

  list.wait();

 

  } catch (InterruptedException e) {

 

  e.printStackTrace();

 

  }

 

  }

 

  // 消费条件满足情况下,消费 num 个产品

 

  for (int i = 1; i <= num; ++i) {

 

  list.remove();

 

  }

 

  System.out.print(" 【已经消费产品数】 :" + num);

 

  System.out.println(" 【现仓储 ) 量为】 :" + list.size());

 

  list.notifyAll();

 

  }

 

  }

 

  // get/set 方法

 

  public LinkedList getList() {

 

  return list;

 

  }

 

  public void setList(LinkedList list) {

 

  this.list = list;

 

  }

 

  public int getMAX_SIZE() {

 

  return MAX_SIZE;

 

  }

 

  }

 

  ```

 

  仓库类:(await()/signal() 方法 )

 

  ```

 

  public class Storage { // 仓库最大存储量

 

  // 仓库最大存储量

 

  private final int MAX_SIZE = 100;

 

  // 仓库存储的载体

 

  private LinkedList list = new LinkedList();

 

  // 锁

 

  private final Lock lock = new ReentrantLock();

 

  // 仓库满的条件变量

 

  private final Condition full = lock.newCondition();

 

  // 仓库空的条件变量

 

  private final Condition empty = lock.newCondition();

 

  // 生产 num 个产品

 

  public void produce(int num) {

 

  // 获得锁

 

  lock.lock();

 

  // 如果仓库剩余容量不足

 

  while (list.size() + num > MAX_SIZE) {

 

  System.out.print(" 【要生产的产品数量】 :" + num);

 

  System.out.println(" 【库存量】 :" + list.size() + " 暂时不能执行生产任务 !");

 

  try {

 

  // 由于条件不满足,生产阻塞

 

  full.await();

 

  } catch (InterruptedException e) {

 

  e.printStackTrace();

 

  }

 

  }

 

  // 生产条件满足情况下,生产 num 个产品

 

  for (int i = 1; i <= num; ++i) {

 

  list.add(new Object());

 

  }

 

  System.out.print(" 【已经生产产品数】 :" + num);

 

  System.out.println(" 【现仓储量为】 :" + list.size());

 

  // 唤醒其他所有线程

 

  full.signalAll();

 

  empty.signalAll();

 

  // 释放锁

 

  lock.unlock();

 

  }

 

  // 消费 num 个产品

 

  public void consume(int num) {

 

  // 获得锁

 

  lock.lock();

 

  // 如果仓库存储量不足

 

  while (list.size() < num) {

 

  System.out.print(" 【要消费的产品数量】 :" + num);

 

  System.out.println(" 【库存量】 :" + list.size() + " 暂时不能执行生产任务 !");

 

  try {

 

  // 由于条件不满足,消费阻塞

 

  empty.await();

 

  } catch (InterruptedException e) {

 

  e.printStackTrace();

 

  }

 

  }

 

  // 消费条件满足情况下,消费 num 个产品

 

  for (int i = 1; i <= num; ++i) {

 

  list.remove();

 

  }

 

  System.out.print(" 【已经消费产品数】 :" + num);

 

  System.out.println(" 【现仓储 ) 量为】 :" + list.size());

 

  // 唤醒其他所有线程

 

  full.signalAll();

 

  empty.signalAll();

 

  // 释放锁

 

  lock.unlock();

 

  }

 

  // set/get 方法

 

  public int getMAX_SIZE() {

 

  return MAX_SIZE;

 

  }

 

  public LinkedList getList() {

 

  return list;

 

  }

 

  public void setList(LinkedList list) {

 

  this.list = list;

 

  }

 

  }

 

 


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69913892/viewspace-2658724/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
欢迎关注公众号:好程序员特训营 web前端教程分享 723729549 大数据教程分享 703503210

注册时间:2019-03-20

  • 博文量
    539
  • 访问量
    410772