其实此题是模拟多用户对相同资源的操作。网上大多解法只是解决了基本的同步问题,并未解决对于资源的控制。
- 可使用lock condition条件对象及await() signalALL()来解决问题。
package com.javalearn;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Resources {
private int data;
private Lock lock;
private Condition lastData;
public Resources() {
this.data = 0;
this.lock = new ReentrantLock();
this.lastData = lock.newCondition();
}
public void dec() throws InterruptedException {
lock.lock();
try {
while (this.data==0)
lastData.await();
this.data--;
System.out.println(Thread.currentThread()+" "+this.data);
lastData.signalAll();
} finally {
lock.unlock();
}
}
public void inc() throws InterruptedException {
lock.lock();
try {
while (this.data==1)
lastData.await();
this.data++;
System.out.println(Thread.currentThread()+" "+this.data);
lastData.signalAll();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Resources res = new Resources();
for (int i = 0; i < 100; i++) {
new Thread(()->{
for (int j = 0; j < 100; j++) {
try {
res.dec();
Thread.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"decrement"+i).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
try {
res.inc();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"increment"+i).start();
}
}
}
- 可使用synchronized及wait()和notifyALL()来解决。
package com.javalearn;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Resources {
private int data = 0;
public synchronized void dec() throws InterruptedException {
while (this.data==0)
wait();
this.data--;
System.out.println(Thread.currentThread()+" "+this.data);
notifyAll();
}
public synchronized void inc() throws InterruptedException {
while (this.data==1)
wait();
this.data++;
System.out.println(Thread.currentThread()+" "+this.data);
notifyAll();
}
public static void main(String[] args) {
Resources res = new Resources();
for (int i = 0; i < 100; i++) {//此处设置加法线程数量
new Thread(()->{
for (int j = 0; j < 100; j++) {
try {
res.dec();
Thread.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"decrement"+i).start();
}
for (int i = 0; i < 10; i++) {//此处设置减法线程数量
new Thread(()->{
for (int j = 0; j < 1000; j++) {
try {
res.inc();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"increment"+i).start();
}
}
}
两种代码都是比较标准的模板,可以参考使用。建议使用较为简洁的第二种类。l