This is actually a practice in class. But I am using a different way to solve this problem. It doesn't look bad.
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.*;
class Customer implements Runnable {
private CraftsStore craftsStore = new CraftsStore();
private int amount;
private int id;
int numOfDone;
Customer(CraftsStore craftsStore, int n, int id) {
this.craftsStore = craftsStore;
amount = n;
numOfDone = 0;
this.id = id;
}
@Override
public void run() {
for (int i = 1; i <= amount; ++i) {
try {
CraftsMan c;
c = craftsStore.craftsMan.take();
c.produce(id, i);
craftsStore.craftsMan.put(c);
synchronized (craftsStore.manager) {
if (!craftsStore.manager.check()) {
System.out.println("customer " + id + ", product " + i + " is nooooot OK.");
--i;
continue;
}
}
System.out.println("customer " + id + ", product " + i + " is OK!.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("customer " + id + " is all done.");
synchronized (craftsStore.cashier) {
try {
craftsStore.cashier.checkOut(id);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (craftsStore.countOfCustomer) {
++craftsStore.countOfCustomer;
}
}
}
class CraftsMan {
private int id;
CraftsMan(int id) {
this.id = id;
}
void produce(int id, int number) throws InterruptedException {
Random random = new Random();
TimeUnit.MILLISECONDS.sleep(200 + random.nextInt(100));
System.out.println("customer " + id + ", product " + number + " is finished! by craftsman" + this.id + ".");
}
}
class Manager {
boolean check() {
Random random = new Random();
if (random.nextInt(10) % 10 == 0)
return false;
return true;
}
}
class Cashier {
void checkOut(int id) throws InterruptedException {
Random random = new Random();
TimeUnit.MILLISECONDS.sleep(400 + random.nextInt(100));
System.out.println("customer " + id + " has paid!.");
}
}
public class CraftsStore {
Cashier cashier;
Manager manager;
LinkedBlockingDeque<CraftsMan> craftsMan;
Integer countOfCustomer;
CraftsStore() {
cashier = new Cashier();
manager = new Manager();
craftsMan = new LinkedBlockingDeque<>(3);
craftsMan.addAll(Arrays.asList(new CraftsMan(1), new CraftsMan(2), new CraftsMan(3)));
countOfCustomer = 0;
}
public static void main(String[] args) throws InterruptedException {
Random random = new Random();
CraftsStore craftsStore = new CraftsStore();
ExecutorService exec = Executors.newCachedThreadPool();
for (int id = 0; id < 10; ++id) {
exec.execute(new Customer(craftsStore, random.nextInt(5) + 3, id));
TimeUnit.MILLISECONDS.sleep(200 + random.nextInt(500));
}
exec.shutdown();
}
}