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

好程序员面试题分享同一资源多线程并发访问时的完整性,常用的同步方法是采用信号或加锁机制,确保资源在任意时刻至多被一个线程访问。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;

 

}

 

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值